165 lines
4.8 KiB
PowerShell
165 lines
4.8 KiB
PowerShell
$ErrorActionPreference = "Stop"
|
|
|
|
& powershell -ExecutionPolicy Bypass -File scripts/dev/windows/check-workspace.ps1
|
|
|
|
$expectedOrigin = "ssh://git@git.txyundm.cn:2222/panda/qipai.git"
|
|
$requiredPaths = @(
|
|
"V5.0.md",
|
|
"V4.8.md",
|
|
"setup.sh",
|
|
"deploy/README.md",
|
|
"deploy/VERSION",
|
|
"docs/current-baseline.md",
|
|
"docs/module-status.md",
|
|
"docs/feature-status.md",
|
|
"docs/workspace-status.md",
|
|
"docs/reference-inventory.md",
|
|
"docs/reference-redaction-log.md",
|
|
"docs/repository-completeness.md",
|
|
"scripts/dev/windows/check-workspace.ps1",
|
|
"scripts/dev/windows/check-reference.ps1",
|
|
"scripts/dev/windows/check-repo-completeness.ps1",
|
|
"scripts/dev/windows/check-secrets.ps1",
|
|
"scripts/dev/windows/check-large-files.ps1",
|
|
"scripts/dev/windows/check-line-endings.ps1",
|
|
"scripts/dev/wsl/check-env.sh",
|
|
"scripts/dev/wsl/check-emqx.sh",
|
|
"scripts/dev/wsl/start-emqx.sh",
|
|
"scripts/dev/wsl/stop-emqx.sh",
|
|
"scripts/dev/wsl/check-workspace.sh",
|
|
"scripts/dev/wsl/prepare-test-copy.sh",
|
|
"scripts/dev/wsl/verify-linux.sh",
|
|
"scripts/dev/wsl/mqtt-smoke.sh",
|
|
"scripts/dev/wsl/check-gitea-ssh.sh",
|
|
"scripts/dev/wsl/check-api-domain.sh",
|
|
"scripts/dev/wsl/cleanup-test-copy.sh"
|
|
)
|
|
|
|
$forbiddenTrackedPatterns = @(
|
|
'(^|/)\.env$',
|
|
'(^|/)\.env\.(?!example$)',
|
|
'\.(pem|key|p12|crt|csr)$',
|
|
'(^|/)node_modules/',
|
|
'(^|/)dist/',
|
|
'(^|/)build/',
|
|
'(^|/)coverage/',
|
|
'(^|/)\.cache/',
|
|
'(^|/)\.vite/',
|
|
'(^|/)logs/',
|
|
'\.log$',
|
|
'(^|/)uploads/',
|
|
'(^|/)backup/',
|
|
'(^|/)backups/',
|
|
'\.bak$',
|
|
'\.dump$',
|
|
'\.sql\.gz$',
|
|
'^scripts/dev/wsl/mqtt-smoke\.env$'
|
|
)
|
|
|
|
$allowedTrackedRegex = @(
|
|
'^deploy/backup/'
|
|
)
|
|
|
|
function Convert-ToRepoPath {
|
|
param([string]$Path)
|
|
return ($Path -replace '\\', '/').TrimStart('./')
|
|
}
|
|
|
|
function Assert-GitTracked {
|
|
param([string]$Path)
|
|
& git -c core.quotePath=false ls-files --error-unmatch -- $Path *> $null
|
|
if ($LASTEXITCODE -ne 0) {
|
|
throw "Required repository file is missing or untracked: $Path"
|
|
}
|
|
}
|
|
|
|
$origin = & git remote get-url origin
|
|
if ($origin -ne $expectedOrigin) {
|
|
throw "Invalid origin: $origin"
|
|
}
|
|
|
|
$branch = & git branch --show-current
|
|
if ($branch -ne "main") {
|
|
throw "Branch must be main, actual: $branch"
|
|
}
|
|
|
|
$aheadBehind = (& git rev-list --left-right --count main...origin/main).Trim()
|
|
$aheadBehindParts = $aheadBehind -split '\s+'
|
|
$ahead = [int]$aheadBehindParts[0]
|
|
$behind = [int]$aheadBehindParts[1]
|
|
if ($behind -gt 0) {
|
|
throw "Local main is behind origin/main or diverged: $aheadBehind"
|
|
}
|
|
if ($ahead -gt 0) {
|
|
Write-Host "INFO: local main is ahead of origin/main; push and verify remote after commit."
|
|
}
|
|
else {
|
|
Write-Host "PASS: local main matches origin/main."
|
|
}
|
|
|
|
foreach ($path in $requiredPaths) {
|
|
if (-not (Test-Path $path)) {
|
|
throw "Required path does not exist: $path"
|
|
}
|
|
Assert-GitTracked $path
|
|
}
|
|
|
|
$untracked = @(& git -c core.quotePath=false status --porcelain=v1 --untracked-files=all | Where-Object { $_.StartsWith("?? ") })
|
|
if ($untracked.Count -gt 0) {
|
|
$untracked | ForEach-Object { Write-Host "UNTRACKED: $_" }
|
|
throw "Untracked files found. Track deliverables or add an explicit ignore rule."
|
|
}
|
|
|
|
$nestedGitDirs = @(Get-ChildItem -Force -Directory -Recurse -Filter ".git" -ErrorAction SilentlyContinue | Where-Object {
|
|
$_.FullName -ne (Join-Path (Get-Location).Path ".git")
|
|
})
|
|
if ($nestedGitDirs.Count -gt 0) {
|
|
$nestedGitDirs | ForEach-Object { Write-Host "NESTED-GIT: $($_.FullName)" }
|
|
throw "Nested Git directories found."
|
|
}
|
|
|
|
$gitModules = @(& git -c core.quotePath=false ls-files -- ".gitmodules")
|
|
if ($gitModules.Count -gt 0) {
|
|
$gitModules | ForEach-Object { Write-Host "SUBMODULE-METADATA: $_" }
|
|
throw "Submodule metadata is tracked; V5.0 requires a single repository."
|
|
}
|
|
|
|
$tracked = @(& git -c core.quotePath=false ls-files)
|
|
$forbiddenTracked = @()
|
|
foreach ($file in $tracked) {
|
|
$repoPath = Convert-ToRepoPath $file
|
|
$isAllowed = $false
|
|
foreach ($allowed in $allowedTrackedRegex) {
|
|
if ($repoPath -match $allowed) {
|
|
$isAllowed = $true
|
|
break
|
|
}
|
|
}
|
|
if ($isAllowed) {
|
|
continue
|
|
}
|
|
|
|
foreach ($pattern in $forbiddenTrackedPatterns) {
|
|
if ($repoPath -match $pattern) {
|
|
$forbiddenTracked += $repoPath
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($forbiddenTracked.Count -gt 0) {
|
|
$forbiddenTracked | Sort-Object -Unique | ForEach-Object { Write-Host "FORBIDDEN-TRACKED: $_" }
|
|
throw "Forbidden runtime, secret, dependency, build, backup, log, or upload files are tracked."
|
|
}
|
|
|
|
& git diff --check
|
|
& powershell -ExecutionPolicy Bypass -File scripts/dev/windows/check-secrets.ps1
|
|
& powershell -ExecutionPolicy Bypass -File scripts/dev/windows/check-line-endings.ps1
|
|
|
|
$ignored = @(& git -c core.quotePath=false status --ignored --short --untracked-files=all | Where-Object { $_ -like "!! *" })
|
|
if ($ignored.Count -gt 0) {
|
|
Write-Host ("INFO: ignored local-only files present: {0}" -f $ignored.Count)
|
|
}
|
|
|
|
Write-Host "PASS: repository completeness check passed."
|