Files
qipai/scripts/dev/windows/check-repo-completeness.ps1
T
2026-06-16 20:37:55 +08:00

173 lines
5.1 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",
"README.md",
"V5.1.md",
"V5.2.md",
"docs/configuration.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-backend.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/windows/check-release-manifest.ps1",
"scripts/dev/windows/check-readme-config.ps1",
"scripts/dev/windows/check-status-docs.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."