1+ param (
2+ [Parameter (Mandatory = $true )]
3+ [string ]$RepoPath
4+ )
5+
6+ $ErrorActionPreference = " Stop"
7+ $RepoPath = (Resolve-Path - LiteralPath $RepoPath ).Path
8+ Push-Location $RepoPath
9+
10+ $findings = New-Object System.Collections.Generic.List[object ]
11+
12+ function Add-Finding {
13+ param (
14+ [string ]$Path ,
15+ [string ]$Category ,
16+ [string ]$Severity ,
17+ [string ]$Reason
18+ )
19+ $script :findings.Add ([pscustomobject ]@ {
20+ Path = $Path
21+ Category = $Category
22+ Severity = $Severity
23+ Reason = $Reason
24+ }) | Out-Null
25+ }
26+
27+ $recommended = @ (
28+ " __pycache__/" ,
29+ " *.pyc" ,
30+ " .pytest_cache/" ,
31+ " .env" ,
32+ " AGENTS.md" ,
33+ " CLAUDE.md" ,
34+ " .claudeignore"
35+ )
36+
37+ $gitignorePath = Join-Path $RepoPath " .gitignore"
38+ $gitignoreText = " "
39+ if (Test-Path $gitignorePath ) {
40+ $gitignoreText = Get-Content $gitignorePath - Raw
41+ } else {
42+ Add-Finding " .gitignore" " missing-file" " review" " No root .gitignore file"
43+ }
44+
45+ foreach ($pattern in $recommended ) {
46+ $escaped = [regex ]::Escape($pattern )
47+ if ($gitignoreText -and ($gitignoreText -notmatch $escaped )) {
48+ Add-Finding $pattern " missing-recommended-rule" " review" " Recommended public-prep ignore rule not present in .gitignore"
49+ }
50+ }
51+
52+ $ignoredTracked = @ (git ls- files - ci -- exclude- standard 2> $null )
53+ foreach ($rel in $ignoredTracked ) {
54+ if (-not $rel ) { continue }
55+ $rule = (git check- ignore - v $rel 2> $null | Select-Object - First 1 )
56+ Add-Finding $rel " tracked-but-ignored" " blocked" " Tracked file matches ignore rule: $rule "
57+ }
58+
59+ Write-Output " === Gitignore Consistency ==="
60+ Write-Output " Repository: $RepoPath "
61+ Write-Output " Tracked files: $ ( (git ls- files | Measure-Object ).Count) "
62+
63+ $blocked = @ ($findings | Where-Object { $_.Severity -eq " blocked" })
64+ $review = @ ($findings | Where-Object { $_.Severity -eq " review" })
65+
66+ if ($findings.Count -eq 0 ) {
67+ Write-Output " Findings: none"
68+ Write-Output " result: PASS"
69+ Pop-Location
70+ exit 0
71+ }
72+
73+ Write-Output " Findings: $ ( $findings.Count ) (blocked: $ ( $blocked.Count ) , review: $ ( $review.Count ) )"
74+ foreach ($item in $findings ) {
75+ Write-Output " [$ ( $item.Severity ) /$ ( $item.Category ) ] $ ( $item.Path ) — $ ( $item.Reason ) "
76+ }
77+
78+ if ($blocked.Count -gt 0 ) {
79+ Write-Output " result: BLOCKED"
80+ Pop-Location
81+ exit 1
82+ }
83+
84+ Write-Output " result: PASS_WITH_REVIEW"
85+ Pop-Location
86+ exit 0
0 commit comments