fix(shims): skip PowerShell common params in CLI forwarders
Lint / pssa (push) Successful in 28s
Lint / python (push) Successful in 59s

The blind -X -> --x shims forwarded PowerShell common parameters
(-ErrorAction, -Verbose, ...) to the Python CLI, e.g.
Measure-CIBenchmark.ps1 -> Remove-BuildVM.ps1 -ErrorAction
SilentlyContinue produced `ci_orchestrator vm remove --error-action`
-> "No such option" -> destroy failed (orphan VM left). Skip
common switches and consume value-taking ones. Applied to all 7
blind-loop shims; param-style shims (New-BuildVM, Invoke-RemoteBuild,
Get-BuildArtifacts) are not affected. PSSA clean.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Simone
2026-05-17 23:03:24 +02:00
parent f7cfc74290
commit f0a94b86b3
7 changed files with 418 additions and 317 deletions
+37 -23
View File
@@ -1,23 +1,37 @@
#Requires -Version 5.1 #Requires -Version 5.1
Set-StrictMode -Version Latest Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop' $ErrorActionPreference = 'Stop'
# Shim: delegates to the Python ci_orchestrator CLI. # Shim: delegates to the Python ci_orchestrator CLI.
# Original PS implementation moved to git history; see plans/A2-closeout.md. # Original PS implementation moved to git history; see plans/A2-closeout.md.
$pyArgs = @() # PowerShell common params (-ErrorAction etc.) must not be forwarded
foreach ($a in $args) { # to the Python CLI. Value-taking ones also consume the next token.
if ($a -is [string] -and $a.Length -gt 1 -and $a.StartsWith('-') -and -not $a.StartsWith('--')) { $commonWithValue = @{
$name = $a.Substring(1) erroraction = $true; warningaction = $true; informationaction = $true
$kebab = [Regex]::Replace($name, '(?<=[a-z0-9])([A-Z])', '-$1') progressaction = $true; errorvariable = $true; warningvariable = $true
$kebab = [Regex]::Replace($kebab, '([A-Z]+)([A-Z][a-z])', '$1-$2') informationvariable = $true; outvariable = $true; outbuffer = $true
$pyArgs += '--' + $kebab.ToLower() pipelinevariable = $true
} }
else { $commonSwitch = @{ verbose = $true; debug = $true; whatif = $true; confirm = $true }
$pyArgs += $a
} $pyArgs = @()
} for ($i = 0; $i -lt $args.Count; $i++) {
$a = $args[$i]
$venvPython = $env:CI_VENV_PYTHON if ($a -is [string] -and $a.Length -gt 1 -and $a.StartsWith('-') -and -not $a.StartsWith('--')) {
if (-not $venvPython) { $venvPython = 'F:\CI\python\venv\Scripts\python.exe' } $name = $a.Substring(1)
& $venvPython -m ci_orchestrator vm cleanup @pyArgs $lname = $name.ToLower()
exit $LASTEXITCODE if ($commonSwitch.ContainsKey($lname)) { continue }
if ($commonWithValue.ContainsKey($lname)) { $i++; continue }
$kebab = [Regex]::Replace($name, '(?<=[a-z0-9])([A-Z])', '-$1')
$kebab = [Regex]::Replace($kebab, '([A-Z]+)([A-Z][a-z])', '$1-$2')
$pyArgs += '--' + $kebab.ToLower()
}
else {
$pyArgs += $a
}
}
$venvPython = $env:CI_VENV_PYTHON
if (-not $venvPython) { $venvPython = 'F:\CI\python\venv\Scripts\python.exe' }
& $venvPython -m ci_orchestrator vm cleanup @pyArgs
exit $LASTEXITCODE
+215 -201
View File
@@ -1,201 +1,215 @@
#Requires -Version 5.1 #Requires -Version 5.1
Set-StrictMode -Version Latest Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop' $ErrorActionPreference = 'Stop'
# Shim: delegates to the Python ci_orchestrator CLI. # Shim: delegates to the Python ci_orchestrator CLI.
# Original PS implementation moved to git history; see plans/A2-closeout.md. # Original PS implementation moved to git history; see plans/A2-closeout.md.
$pyArgs = @() # PowerShell common params (-ErrorAction etc.) must not be forwarded
foreach ($a in $args) { # to the Python CLI. Value-taking ones also consume the next token.
if ($a -is [string] -and $a.Length -gt 1 -and $a.StartsWith('-') -and -not $a.StartsWith('--')) { $commonWithValue = @{
$name = $a.Substring(1) erroraction = $true; warningaction = $true; informationaction = $true
$kebab = [Regex]::Replace($name, '(?<=[a-z0-9])([A-Z])', '-$1') progressaction = $true; errorvariable = $true; warningvariable = $true
$kebab = [Regex]::Replace($kebab, '([A-Z]+)([A-Z][a-z])', '$1-$2') informationvariable = $true; outvariable = $true; outbuffer = $true
$pyArgs += '--' + $kebab.ToLower() pipelinevariable = $true
} }
else { $commonSwitch = @{ verbose = $true; debug = $true; whatif = $true; confirm = $true }
$pyArgs += $a
} $pyArgs = @()
} for ($i = 0; $i -lt $args.Count; $i++) {
$a = $args[$i]
$venvPython = $env:CI_VENV_PYTHON if ($a -is [string] -and $a.Length -gt 1 -and $a.StartsWith('-') -and -not $a.StartsWith('--')) {
if (-not $venvPython) { $venvPython = 'F:\CI\python\venv\Scripts\python.exe' } $name = $a.Substring(1)
& $venvPython -m ci_orchestrator report job @pyArgs $lname = $name.ToLower()
exit $LASTEXITCODE if ($commonSwitch.ContainsKey($lname)) { continue }
if ($commonWithValue.ContainsKey($lname)) { $i++; continue }
$kebab = [Regex]::Replace($name, '(?<=[a-z0-9])([A-Z])', '-$1')
.DESCRIPTION $kebab = [Regex]::Replace($kebab, '([A-Z]+)([A-Z][a-z])', '$1-$2')
Scans F:\CI\Logs\ (or a custom path) for invoke-ci.jsonl files and $pyArgs += '--' + $kebab.ToLower()
prints a compact table with job ID, status, total elapsed time, and the }
last error message (if any). else {
$pyArgs += $a
Each row corresponds to one completed (or failed) CI job. }
Use -JobId to inspect a single job in detail. }
.PARAMETER LogDir $venvPython = $env:CI_VENV_PYTHON
Base directory containing per-job log subdirectories. if (-not $venvPython) { $venvPython = 'F:\CI\python\venv\Scripts\python.exe' }
Default: F:\CI\Logs & $venvPython -m ci_orchestrator report job @pyArgs
exit $LASTEXITCODE
.PARAMETER Last
Show only the N most recent jobs (sorted by job-start timestamp).
Default: 20 .DESCRIPTION
Scans F:\CI\Logs\ (or a custom path) for invoke-ci.jsonl files and
.PARAMETER JobId prints a compact table with job ID, status, total elapsed time, and the
When specified, shows a detailed phase-by-phase breakdown for that job. last error message (if any).
.PARAMETER Failed Each row corresponds to one completed (or failed) CI job.
When specified, filters to failed jobs only. Use -JobId to inspect a single job in detail.
.EXAMPLE .PARAMETER LogDir
# Show last 20 jobs Base directory containing per-job log subdirectories.
.\Get-CIJobSummary.ps1 Default: F:\CI\Logs
.EXAMPLE .PARAMETER Last
# Show last 5 failed jobs Show only the N most recent jobs (sorted by job-start timestamp).
.\Get-CIJobSummary.ps1 -Last 5 -Failed Default: 20
.EXAMPLE .PARAMETER JobId
# Detailed breakdown for a specific job When specified, shows a detailed phase-by-phase breakdown for that job.
.\Get-CIJobSummary.ps1 -JobId 'run-12345'
#> .PARAMETER Failed
[CmdletBinding()] When specified, filters to failed jobs only.
param(
[string] $LogDir = 'F:\CI\Logs', .EXAMPLE
# Show last 20 jobs
[ValidateRange(1, 1000)] .\Get-CIJobSummary.ps1
[int] $Last = 20,
.EXAMPLE
[string] $JobId = '', # Show last 5 failed jobs
.\Get-CIJobSummary.ps1 -Last 5 -Failed
[switch] $Failed
) .EXAMPLE
# Detailed breakdown for a specific job
Set-StrictMode -Version Latest .\Get-CIJobSummary.ps1 -JobId 'run-12345'
$ErrorActionPreference = 'Stop' #>
[CmdletBinding()]
# ── Helpers ──────────────────────────────────────────────────────────────────── param(
function Format-SecToHMS { [string] $LogDir = 'F:\CI\Logs',
param([int] $Seconds)
if ($Seconds -lt 0) { return '?' } [ValidateRange(1, 1000)]
$h = [math]::Floor($Seconds / 3600) [int] $Last = 20,
$m = [math]::Floor(($Seconds % 3600) / 60)
$s = $Seconds % 60 [string] $JobId = '',
if ($h -gt 0) { return '{0}h{1:00}m{2:00}s' -f $h, $m, $s }
return '{0}m{1:00}s' -f $m, $s [switch] $Failed
} )
function Read-JobEvents { Set-StrictMode -Version Latest
param([string] $JsonlPath) $ErrorActionPreference = 'Stop'
$events = [System.Collections.Generic.List[PSCustomObject]]::new()
foreach ($line in (Get-Content $JsonlPath -Encoding UTF8 -ErrorAction SilentlyContinue)) { # ── Helpers ────────────────────────────────────────────────────────────────────
$line = $line.Trim() function Format-SecToHMS {
if (-not $line) { continue } param([int] $Seconds)
try { if ($Seconds -lt 0) { return '?' }
$events.Add(($line | ConvertFrom-Json)) $h = [math]::Floor($Seconds / 3600)
} catch { $m = [math]::Floor(($Seconds % 3600) / 60)
Write-Debug "[Get-CIJobSummary] Skipping malformed JSONL line in $JsonlPath" $s = $Seconds % 60
} if ($h -gt 0) { return '{0}h{1:00}m{2:00}s' -f $h, $m, $s }
} return '{0}m{1:00}s' -f $m, $s
return $events }
}
function Read-JobEvents {
# ── Validate log dir ──────────────────────────────────────────────────────── param([string] $JsonlPath)
if (-not (Test-Path $LogDir -PathType Container)) { $events = [System.Collections.Generic.List[PSCustomObject]]::new()
Write-Warning "Log directory not found: $LogDir" foreach ($line in (Get-Content $JsonlPath -Encoding UTF8 -ErrorAction SilentlyContinue)) {
exit 1 $line = $line.Trim()
} if (-not $line) { continue }
try {
# ── Single-job detail mode ────────────────────────────────────────────────── $events.Add(($line | ConvertFrom-Json))
if ($JobId -ne '') { } catch {
$jsonlPath = Join-Path $LogDir (Join-Path $JobId 'invoke-ci.jsonl') Write-Debug "[Get-CIJobSummary] Skipping malformed JSONL line in $JsonlPath"
if (-not (Test-Path $jsonlPath)) { }
Write-Warning "No JSONL log found for job '$JobId' at: $jsonlPath" }
exit 1 return $events
} }
$events = Read-JobEvents -JsonlPath $jsonlPath
if ($events.Count -eq 0) { # ── Validate log dir ────────────────────────────────────────────────────────
Write-Warning "JSONL file is empty or unreadable: $jsonlPath" if (-not (Test-Path $LogDir -PathType Container)) {
exit 1 Write-Warning "Log directory not found: $LogDir"
} exit 1
Write-Host "`nJob: $JobId" }
Write-Host ('=' * 60)
Write-Host ('{0,-35} {1,-10} {2}' -f 'Phase', 'Status', 'Timestamp') # ── Single-job detail mode ──────────────────────────────────────────────────
Write-Host ('{0,-35} {1,-10} {2}' -f ('-'*35), ('-'*10), ('-'*24)) if ($JobId -ne '') {
foreach ($ev in $events) { $jsonlPath = Join-Path $LogDir (Join-Path $JobId 'invoke-ci.jsonl')
$ts = if ($ev.ts) { $ev.ts } else { '' } if (-not (Test-Path $jsonlPath)) {
Write-Host ('{0,-35} {1,-10} {2}' -f $ev.phase, $ev.status, $ts) Write-Warning "No JSONL log found for job '$JobId' at: $jsonlPath"
} exit 1
# Print error if present }
$failEvent = $events | Where-Object { $_.status -eq 'failure' } | Select-Object -Last 1 $events = Read-JobEvents -JsonlPath $jsonlPath
if ($failEvent -and $failEvent.data -and $failEvent.data.error) { if ($events.Count -eq 0) {
Write-Host "`nError: $($failEvent.data.error)" Write-Warning "JSONL file is empty or unreadable: $jsonlPath"
} exit 1
exit 0 }
} Write-Host "`nJob: $JobId"
Write-Host ('=' * 60)
# ── Scan all job JSONL files ───────────────────────────────────────────────── Write-Host ('{0,-35} {1,-10} {2}' -f 'Phase', 'Status', 'Timestamp')
$jsonlFiles = Get-ChildItem -Path $LogDir -Recurse -Filter 'invoke-ci.jsonl' -ErrorAction SilentlyContinue | Write-Host ('{0,-35} {1,-10} {2}' -f ('-'*35), ('-'*10), ('-'*24))
Sort-Object { $_.LastWriteTime } -Descending foreach ($ev in $events) {
$ts = if ($ev.ts) { $ev.ts } else { '' }
if ($jsonlFiles.Count -eq 0) { Write-Host ('{0,-35} {1,-10} {2}' -f $ev.phase, $ev.status, $ts)
Write-Host "No invoke-ci.jsonl files found under $LogDir" }
exit 0 # Print error if present
} $failEvent = $events | Where-Object { $_.status -eq 'failure' } | Select-Object -Last 1
if ($failEvent -and $failEvent.data -and $failEvent.data.error) {
$rows = [System.Collections.Generic.List[PSCustomObject]]::new() Write-Host "`nError: $($failEvent.data.error)"
}
foreach ($file in $jsonlFiles) { exit 0
$events = Read-JobEvents -JsonlPath $file.FullName }
if ($events.Count -eq 0) { continue }
# ── Scan all job JSONL files ─────────────────────────────────────────────────
$jobEvent = $events | Where-Object { $_.phase -eq 'job' -and $_.status -eq 'start' } | Select-Object -First 1 $jsonlFiles = Get-ChildItem -Path $LogDir -Recurse -Filter 'invoke-ci.jsonl' -ErrorAction SilentlyContinue |
$successEvent= $events | Where-Object { $_.phase -eq 'job' -and $_.status -eq 'success' } | Select-Object -First 1 Sort-Object { $_.LastWriteTime } -Descending
$failEvent = $events | Where-Object { $_.phase -eq 'job' -and $_.status -eq 'failure' } | Select-Object -First 1
if ($jsonlFiles.Count -eq 0) {
$jId = if ($events[0].jobId) { $events[0].jobId } else { (Split-Path (Split-Path $file.FullName -Parent) -Leaf) } Write-Host "No invoke-ci.jsonl files found under $LogDir"
$started = if ($jobEvent -and $jobEvent.ts) { $jobEvent.ts } else { '' } exit 0
}
if ($successEvent) {
$status = 'success' $rows = [System.Collections.Generic.List[PSCustomObject]]::new()
$elSec = if ($successEvent.data -and $null -ne $successEvent.data.elapsedSec) { [int]$successEvent.data.elapsedSec } else { -1 }
$errMsg = '' foreach ($file in $jsonlFiles) {
} elseif ($failEvent) { $events = Read-JobEvents -JsonlPath $file.FullName
$status = 'FAILED' if ($events.Count -eq 0) { continue }
$elSec = if ($failEvent.data -and $null -ne $failEvent.data.elapsedSec) { [int]$failEvent.data.elapsedSec } else { -1 }
$errMsg = if ($failEvent.data -and $failEvent.data.error) { "$($failEvent.data.error)" } else { '' } $jobEvent = $events | Where-Object { $_.phase -eq 'job' -and $_.status -eq 'start' } | Select-Object -First 1
# Truncate error for table display $successEvent= $events | Where-Object { $_.phase -eq 'job' -and $_.status -eq 'success' } | Select-Object -First 1
if ($errMsg.Length -gt 60) { $errMsg = $errMsg.Substring(0, 57) + '...' } $failEvent = $events | Where-Object { $_.phase -eq 'job' -and $_.status -eq 'failure' } | Select-Object -First 1
} else {
$status = 'in-progress' $jId = if ($events[0].jobId) { $events[0].jobId } else { (Split-Path (Split-Path $file.FullName -Parent) -Leaf) }
$elSec = -1 $started = if ($jobEvent -and $jobEvent.ts) { $jobEvent.ts } else { '' }
$errMsg = ''
} if ($successEvent) {
$status = 'success'
$rows.Add([PSCustomObject]@{ $elSec = if ($successEvent.data -and $null -ne $successEvent.data.elapsedSec) { [int]$successEvent.data.elapsedSec } else { -1 }
JobId = $jId $errMsg = ''
Status = $status } elseif ($failEvent) {
Elapsed = Format-SecToHMS -Seconds $elSec $status = 'FAILED'
Started = $started $elSec = if ($failEvent.data -and $null -ne $failEvent.data.elapsedSec) { [int]$failEvent.data.elapsedSec } else { -1 }
Error = $errMsg $errMsg = if ($failEvent.data -and $failEvent.data.error) { "$($failEvent.data.error)" } else { '' }
}) # Truncate error for table display
} if ($errMsg.Length -gt 60) { $errMsg = $errMsg.Substring(0, 57) + '...' }
} else {
# ── Apply filters + limit ──────────────────────────────────────────────────── $status = 'in-progress'
if ($Failed) { $elSec = -1
$rows = @($rows | Where-Object { $_.Status -eq 'FAILED' }) $errMsg = ''
} }
$rows = @($rows | Select-Object -First $Last) $rows.Add([PSCustomObject]@{
JobId = $jId
if ($rows.Count -eq 0) { Status = $status
Write-Host "No matching jobs found." Elapsed = Format-SecToHMS -Seconds $elSec
exit 0 Started = $started
} Error = $errMsg
})
# ── Print table ────────────────────────────────────────────────────────────── }
Write-Host "`nCI Job Summary (last $($rows.Count) jobs):"
Write-Host ('{0,-40} {1,-12} {2,-10} {3,-26} {4}' -f 'JobId', 'Status', 'Elapsed', 'Started', 'Error') # ── Apply filters + limit ────────────────────────────────────────────────────
Write-Host ('{0,-40} {1,-12} {2,-10} {3,-26} {4}' -f ('-'*40), ('-'*12), ('-'*10), ('-'*26), ('-'*30)) if ($Failed) {
foreach ($r in $rows) { $rows = @($rows | Where-Object { $_.Status -eq 'FAILED' })
Write-Host ('{0,-40} {1,-12} {2,-10} {3,-26} {4}' -f $r.JobId, $r.Status, $r.Elapsed, $r.Started, $r.Error) }
}
Write-Host '' $rows = @($rows | Select-Object -First $Last)
if ($rows.Count -eq 0) {
Write-Host "No matching jobs found."
exit 0
}
# ── Print table ──────────────────────────────────────────────────────────────
Write-Host "`nCI Job Summary (last $($rows.Count) jobs):"
Write-Host ('{0,-40} {1,-12} {2,-10} {3,-26} {4}' -f 'JobId', 'Status', 'Elapsed', 'Started', 'Error')
Write-Host ('{0,-40} {1,-12} {2,-10} {3,-26} {4}' -f ('-'*40), ('-'*12), ('-'*10), ('-'*26), ('-'*30))
foreach ($r in $rows) {
Write-Host ('{0,-40} {1,-12} {2,-10} {3,-26} {4}' -f $r.JobId, $r.Status, $r.Elapsed, $r.Started, $r.Error)
}
Write-Host ''
+37 -23
View File
@@ -1,23 +1,37 @@
#Requires -Version 5.1 #Requires -Version 5.1
Set-StrictMode -Version Latest Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop' $ErrorActionPreference = 'Stop'
# Shim: delegates to the Python ci_orchestrator CLI. # Shim: delegates to the Python ci_orchestrator CLI.
# Original PS implementation moved to git history; see plans/A4-closeout.md. # Original PS implementation moved to git history; see plans/A4-closeout.md.
$pyArgs = @() # PowerShell common params (-ErrorAction etc.) must not be forwarded
foreach ($a in $args) { # to the Python CLI. Value-taking ones also consume the next token.
if ($a -is [string] -and $a.Length -gt 1 -and $a.StartsWith('-') -and -not $a.StartsWith('--')) { $commonWithValue = @{
$name = $a.Substring(1) erroraction = $true; warningaction = $true; informationaction = $true
$kebab = [Regex]::Replace($name, '(?<=[a-z0-9])([A-Z])', '-$1') progressaction = $true; errorvariable = $true; warningvariable = $true
$kebab = [Regex]::Replace($kebab, '([A-Z]+)([A-Z][a-z])', '$1-$2') informationvariable = $true; outvariable = $true; outbuffer = $true
$pyArgs += '--' + $kebab.ToLower() pipelinevariable = $true
} }
else { $commonSwitch = @{ verbose = $true; debug = $true; whatif = $true; confirm = $true }
$pyArgs += $a
} $pyArgs = @()
} for ($i = 0; $i -lt $args.Count; $i++) {
$a = $args[$i]
$venvPython = $env:CI_VENV_PYTHON if ($a -is [string] -and $a.Length -gt 1 -and $a.StartsWith('-') -and -not $a.StartsWith('--')) {
if (-not $venvPython) { $venvPython = 'F:\CI\python\venv\Scripts\python.exe' } $name = $a.Substring(1)
& $venvPython -m ci_orchestrator job @pyArgs $lname = $name.ToLower()
exit $LASTEXITCODE if ($commonSwitch.ContainsKey($lname)) { continue }
if ($commonWithValue.ContainsKey($lname)) { $i++; continue }
$kebab = [Regex]::Replace($name, '(?<=[a-z0-9])([A-Z])', '-$1')
$kebab = [Regex]::Replace($kebab, '([A-Z]+)([A-Z][a-z])', '$1-$2')
$pyArgs += '--' + $kebab.ToLower()
}
else {
$pyArgs += $a
}
}
$venvPython = $env:CI_VENV_PYTHON
if (-not $venvPython) { $venvPython = 'F:\CI\python\venv\Scripts\python.exe' }
& $venvPython -m ci_orchestrator job @pyArgs
exit $LASTEXITCODE
+18 -1
View File
@@ -4,10 +4,27 @@ $ErrorActionPreference = 'Stop'
# Shim: delegates to the Python ci_orchestrator CLI. # Shim: delegates to the Python ci_orchestrator CLI.
# Original PS implementation moved to git history; see plans/A2-closeout.md. # Original PS implementation moved to git history; see plans/A2-closeout.md.
#
# Callers (e.g. Measure-CIBenchmark.ps1) may pass PowerShell common
# parameters like -ErrorAction SilentlyContinue. Those must NOT be
# forwarded as --error-action etc. (the Python CLI rejects them).
# Value-taking common params consume the following token too.
$commonWithValue = @{
erroraction = $true; warningaction = $true; informationaction = $true
progressaction = $true; errorvariable = $true; warningvariable = $true
informationvariable = $true; outvariable = $true; outbuffer = $true
pipelinevariable = $true
}
$commonSwitch = @{ verbose = $true; debug = $true; whatif = $true; confirm = $true }
$pyArgs = @() $pyArgs = @()
foreach ($a in $args) { for ($i = 0; $i -lt $args.Count; $i++) {
$a = $args[$i]
if ($a -is [string] -and $a.Length -gt 1 -and $a.StartsWith('-') -and -not $a.StartsWith('--')) { if ($a -is [string] -and $a.Length -gt 1 -and $a.StartsWith('-') -and -not $a.StartsWith('--')) {
$name = $a.Substring(1) $name = $a.Substring(1)
$lname = $name.ToLower()
if ($commonSwitch.ContainsKey($lname)) { continue }
if ($commonWithValue.ContainsKey($lname)) { $i++; continue }
$kebab = [Regex]::Replace($name, '(?<=[a-z0-9])([A-Z])', '-$1') $kebab = [Regex]::Replace($name, '(?<=[a-z0-9])([A-Z])', '-$1')
$kebab = [Regex]::Replace($kebab, '([A-Z]+)([A-Z][a-z])', '$1-$2') $kebab = [Regex]::Replace($kebab, '([A-Z]+)([A-Z][a-z])', '$1-$2')
$pyArgs += '--' + $kebab.ToLower() $pyArgs += '--' + $kebab.ToLower()
+37 -23
View File
@@ -1,23 +1,37 @@
#Requires -Version 5.1 #Requires -Version 5.1
Set-StrictMode -Version Latest Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop' $ErrorActionPreference = 'Stop'
# Shim: delegates to the Python ci_orchestrator CLI. # Shim: delegates to the Python ci_orchestrator CLI.
# Original PS implementation moved to git history; see plans/A2-closeout.md. # Original PS implementation moved to git history; see plans/A2-closeout.md.
$pyArgs = @() # PowerShell common params (-ErrorAction etc.) must not be forwarded
foreach ($a in $args) { # to the Python CLI. Value-taking ones also consume the next token.
if ($a -is [string] -and $a.Length -gt 1 -and $a.StartsWith('-') -and -not $a.StartsWith('--')) { $commonWithValue = @{
$name = $a.Substring(1) erroraction = $true; warningaction = $true; informationaction = $true
$kebab = [Regex]::Replace($name, '(?<=[a-z0-9])([A-Z])', '-$1') progressaction = $true; errorvariable = $true; warningvariable = $true
$kebab = [Regex]::Replace($kebab, '([A-Z]+)([A-Z][a-z])', '$1-$2') informationvariable = $true; outvariable = $true; outbuffer = $true
$pyArgs += '--' + $kebab.ToLower() pipelinevariable = $true
} }
else { $commonSwitch = @{ verbose = $true; debug = $true; whatif = $true; confirm = $true }
$pyArgs += $a
} $pyArgs = @()
} for ($i = 0; $i -lt $args.Count; $i++) {
$a = $args[$i]
$venvPython = $env:CI_VENV_PYTHON if ($a -is [string] -and $a.Length -gt 1 -and $a.StartsWith('-') -and -not $a.StartsWith('--')) {
if (-not $venvPython) { $venvPython = 'F:\CI\python\venv\Scripts\python.exe' } $name = $a.Substring(1)
& $venvPython -m ci_orchestrator wait-ready @pyArgs $lname = $name.ToLower()
exit $LASTEXITCODE if ($commonSwitch.ContainsKey($lname)) { continue }
if ($commonWithValue.ContainsKey($lname)) { $i++; continue }
$kebab = [Regex]::Replace($name, '(?<=[a-z0-9])([A-Z])', '-$1')
$kebab = [Regex]::Replace($kebab, '([A-Z]+)([A-Z][a-z])', '$1-$2')
$pyArgs += '--' + $kebab.ToLower()
}
else {
$pyArgs += $a
}
}
$venvPython = $env:CI_VENV_PYTHON
if (-not $venvPython) { $venvPython = 'F:\CI\python\venv\Scripts\python.exe' }
& $venvPython -m ci_orchestrator wait-ready @pyArgs
exit $LASTEXITCODE
+37 -23
View File
@@ -1,23 +1,37 @@
#Requires -Version 5.1 #Requires -Version 5.1
Set-StrictMode -Version Latest Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop' $ErrorActionPreference = 'Stop'
# Shim: delegates to the Python ci_orchestrator CLI. # Shim: delegates to the Python ci_orchestrator CLI.
# Original PS implementation moved to git history; see plans/A2-closeout.md. # Original PS implementation moved to git history; see plans/A2-closeout.md.
$pyArgs = @() # PowerShell common params (-ErrorAction etc.) must not be forwarded
foreach ($a in $args) { # to the Python CLI. Value-taking ones also consume the next token.
if ($a -is [string] -and $a.Length -gt 1 -and $a.StartsWith('-') -and -not $a.StartsWith('--')) { $commonWithValue = @{
$name = $a.Substring(1) erroraction = $true; warningaction = $true; informationaction = $true
$kebab = [Regex]::Replace($name, '(?<=[a-z0-9])([A-Z])', '-$1') progressaction = $true; errorvariable = $true; warningvariable = $true
$kebab = [Regex]::Replace($kebab, '([A-Z]+)([A-Z][a-z])', '$1-$2') informationvariable = $true; outvariable = $true; outbuffer = $true
$pyArgs += '--' + $kebab.ToLower() pipelinevariable = $true
} }
else { $commonSwitch = @{ verbose = $true; debug = $true; whatif = $true; confirm = $true }
$pyArgs += $a
} $pyArgs = @()
} for ($i = 0; $i -lt $args.Count; $i++) {
$a = $args[$i]
$venvPython = $env:CI_VENV_PYTHON if ($a -is [string] -and $a.Length -gt 1 -and $a.StartsWith('-') -and -not $a.StartsWith('--')) {
if (-not $venvPython) { $venvPython = 'F:\CI\python\venv\Scripts\python.exe' } $name = $a.Substring(1)
& $venvPython -m ci_orchestrator monitor disk @pyArgs $lname = $name.ToLower()
exit $LASTEXITCODE if ($commonSwitch.ContainsKey($lname)) { continue }
if ($commonWithValue.ContainsKey($lname)) { $i++; continue }
$kebab = [Regex]::Replace($name, '(?<=[a-z0-9])([A-Z])', '-$1')
$kebab = [Regex]::Replace($kebab, '([A-Z]+)([A-Z][a-z])', '$1-$2')
$pyArgs += '--' + $kebab.ToLower()
}
else {
$pyArgs += $a
}
}
$venvPython = $env:CI_VENV_PYTHON
if (-not $venvPython) { $venvPython = 'F:\CI\python\venv\Scripts\python.exe' }
& $venvPython -m ci_orchestrator monitor disk @pyArgs
exit $LASTEXITCODE
+37 -23
View File
@@ -1,23 +1,37 @@
#Requires -Version 5.1 #Requires -Version 5.1
Set-StrictMode -Version Latest Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop' $ErrorActionPreference = 'Stop'
# Shim: delegates to the Python ci_orchestrator CLI. # Shim: delegates to the Python ci_orchestrator CLI.
# Original PS implementation moved to git history; see plans/A2-closeout.md. # Original PS implementation moved to git history; see plans/A2-closeout.md.
$pyArgs = @() # PowerShell common params (-ErrorAction etc.) must not be forwarded
foreach ($a in $args) { # to the Python CLI. Value-taking ones also consume the next token.
if ($a -is [string] -and $a.Length -gt 1 -and $a.StartsWith('-') -and -not $a.StartsWith('--')) { $commonWithValue = @{
$name = $a.Substring(1) erroraction = $true; warningaction = $true; informationaction = $true
$kebab = [Regex]::Replace($name, '(?<=[a-z0-9])([A-Z])', '-$1') progressaction = $true; errorvariable = $true; warningvariable = $true
$kebab = [Regex]::Replace($kebab, '([A-Z]+)([A-Z][a-z])', '$1-$2') informationvariable = $true; outvariable = $true; outbuffer = $true
$pyArgs += '--' + $kebab.ToLower() pipelinevariable = $true
} }
else { $commonSwitch = @{ verbose = $true; debug = $true; whatif = $true; confirm = $true }
$pyArgs += $a
} $pyArgs = @()
} for ($i = 0; $i -lt $args.Count; $i++) {
$a = $args[$i]
$venvPython = $env:CI_VENV_PYTHON if ($a -is [string] -and $a.Length -gt 1 -and $a.StartsWith('-') -and -not $a.StartsWith('--')) {
if (-not $venvPython) { $venvPython = 'F:\CI\python\venv\Scripts\python.exe' } $name = $a.Substring(1)
& $venvPython -m ci_orchestrator monitor runner @pyArgs $lname = $name.ToLower()
exit $LASTEXITCODE if ($commonSwitch.ContainsKey($lname)) { continue }
if ($commonWithValue.ContainsKey($lname)) { $i++; continue }
$kebab = [Regex]::Replace($name, '(?<=[a-z0-9])([A-Z])', '-$1')
$kebab = [Regex]::Replace($kebab, '([A-Z]+)([A-Z][a-z])', '$1-$2')
$pyArgs += '--' + $kebab.ToLower()
}
else {
$pyArgs += $a
}
}
$venvPython = $env:CI_VENV_PYTHON
if (-not $venvPython) { $venvPython = 'F:\CI\python\venv\Scripts\python.exe' }
& $venvPython -m ci_orchestrator monitor runner @pyArgs
exit $LASTEXITCODE