forked from Alishahryar1/free-claude-code
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathci.ps1
More file actions
210 lines (168 loc) · 5.06 KB
/
Copy pathci.ps1
File metadata and controls
210 lines (168 loc) · 5.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
param(
[string[]] $Only = @(),
[string[]] $Skip = @(),
[switch] $DryRun,
[switch] $Help,
[Parameter(ValueFromRemainingArguments = $true)]
[object[]] $RemainingArgs = @()
)
Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"
$CheckOrder = @(
"suppressions",
"ruff-format",
"ruff-check",
"ty",
"pytest"
)
function Show-Usage {
@"
Usage: ci.ps1 [options]
Runs the local sequence for the same check IDs enforced by GitHub CI.
Requires uv on PATH when running ruff, ty, or pytest checks.
Local ruff checks repair formatting and autofixable lint before later checks.
Checks (in order):
suppressions Ban type ignores and legacy future annotations
ruff-format uv run ruff format
ruff-check uv run ruff check --fix
ty uv run ty check
pytest uv run pytest -v --tb=short
Options:
-Only ID Run only the given check (repeatable)
-Skip ID Skip the given check (repeatable)
-DryRun Print commands without running them.
-Help Show this help text.
"@
}
function Write-Step {
param([string] $Message)
Write-Host ""
Write-Host "==> $Message"
}
function Format-Argument {
param([string] $Value)
if ($Value -match '^[A-Za-z0-9_./:@%+=,\[\]-]+$') {
return $Value
}
return "'" + ($Value -replace "'", "''") + "'"
}
function Invoke-CiCommand {
param(
[string] $FilePath,
[string[]] $Arguments = @()
)
$parts = @($FilePath) + $Arguments
$commandText = ($parts | ForEach-Object { Format-Argument ([string] $_) }) -join " "
Write-Host "+ $commandText"
if (-not $DryRun) {
& $FilePath @Arguments
if ($LASTEXITCODE -ne 0) {
throw "Command failed with exit code ${LASTEXITCODE}: $commandText"
}
}
}
function Test-ValidCheckId {
param([string] $CheckId)
return $CheckOrder -contains $CheckId
}
function Assert-ValidCheckId {
param([string] $CheckId)
if (-not (Test-ValidCheckId $CheckId)) {
throw "unknown check id: $CheckId (expected one of: $($CheckOrder -join ', '))"
}
}
function Test-ShouldRunCheck {
param([string] $CheckId)
if ($Only.Count -gt 0 -and ($Only -notcontains $CheckId)) {
return $false
}
if ($Skip -contains $CheckId) {
return $false
}
return $true
}
function Assert-UvAvailable {
if (-not (Get-Command uv -ErrorAction SilentlyContinue)) {
throw "uv is required but was not found on PATH. Install uv first (see README or scripts/install.ps1)."
}
}
function Test-SelectedChecksNeedUv {
if ($DryRun) {
return $false
}
foreach ($checkId in $CheckOrder) {
if ((Test-ShouldRunCheck $checkId) -and $checkId -ne "suppressions") {
return $true
}
}
return $false
}
function Invoke-SuppressionsCheck {
Write-Step "Ban suppressions and legacy annotations"
$pattern = '# type: ignore|# ty: ignore|from __future__ import annotations'
Write-Host "+ Get-ChildItem -Recurse -Filter *.py (excluding .venv, .git) | Select-String '$pattern'"
if (-not $DryRun) {
$matches = Get-ChildItem -Path . -Recurse -Filter *.py -File |
Where-Object {
$full = $_.FullName
$full -notmatch '[\\/]\.venv[\\/]' -and
$full -notmatch '[\\/]\.git[\\/]'
} |
Select-String -Pattern $pattern
if ($matches) {
$matches | ForEach-Object { Write-Host $_.Line }
throw "type: ignore / ty: ignore comments and legacy future annotations are not allowed. Fix the underlying type/import issue instead."
}
}
}
function Invoke-RuffFormatCheck {
Write-Step "ruff format"
Invoke-CiCommand -FilePath "uv" -Arguments @("run", "ruff", "format")
}
function Invoke-RuffLintCheck {
Write-Step "ruff check --fix"
Invoke-CiCommand -FilePath "uv" -Arguments @("run", "ruff", "check", "--fix")
}
function Invoke-TyCheck {
Write-Step "ty check"
Invoke-CiCommand -FilePath "uv" -Arguments @("run", "ty", "check")
}
function Invoke-PytestCheck {
Write-Step "pytest"
Invoke-CiCommand -FilePath "uv" -Arguments @("run", "pytest", "-v", "--tb=short")
}
function Invoke-Check {
param([string] $CheckId)
switch ($CheckId) {
"suppressions" { Invoke-SuppressionsCheck }
"ruff-format" { Invoke-RuffFormatCheck }
"ruff-check" { Invoke-RuffLintCheck }
"ty" { Invoke-TyCheck }
"pytest" { Invoke-PytestCheck }
default { throw "unknown check id: $CheckId" }
}
}
if ($Help) {
Show-Usage
return
}
if ($RemainingArgs.Count -gt 0) {
Show-Usage
throw "Unknown option: $($RemainingArgs -join ' ')"
}
foreach ($checkId in $Only) {
Assert-ValidCheckId $checkId
}
foreach ($checkId in $Skip) {
Assert-ValidCheckId $checkId
}
if (Test-SelectedChecksNeedUv) {
Assert-UvAvailable
}
foreach ($checkId in $CheckOrder) {
if (Test-ShouldRunCheck $checkId) {
Invoke-Check $checkId
}
}
Write-Host ""
Write-Host "All selected CI checks passed."