feat(scanner): complete localized artifact quality checkpoint
This commit is contained in:
@@ -13,11 +13,89 @@
|
||||
# den "predev"-Hook) ausgefuehrt und raeumt vorherige Instanzen kompromisslos
|
||||
# weg, egal wie sie beendet wurden.
|
||||
|
||||
param(
|
||||
[switch]$SelfTest
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
$project = (Resolve-Path -LiteralPath (Join-Path $PSScriptRoot "..")).Path
|
||||
$electronPath = Join-Path $project "node_modules\electron\dist\electron.exe"
|
||||
$devControlPort = 17317
|
||||
|
||||
function ConvertTo-ComparablePath([string]$Value) {
|
||||
if ([string]::IsNullOrWhiteSpace($Value)) { return "" }
|
||||
try {
|
||||
return [System.IO.Path]::GetFullPath($Value).TrimEnd("\").ToLowerInvariant()
|
||||
} catch {
|
||||
return $Value.Trim().TrimEnd("\").ToLowerInvariant()
|
||||
}
|
||||
}
|
||||
|
||||
function Test-CommandLineContainsPath([string]$CommandLine, [string]$CandidatePath) {
|
||||
if ([string]::IsNullOrWhiteSpace($CommandLine) -or [string]::IsNullOrWhiteSpace($CandidatePath)) { return $false }
|
||||
$normalizedCommand = $CommandLine.Replace("/", "\").ToLowerInvariant()
|
||||
$normalizedCandidate = (ConvertTo-ComparablePath $CandidatePath).Replace("/", "\")
|
||||
return $normalizedCommand.Contains($normalizedCandidate)
|
||||
}
|
||||
|
||||
function Test-GaaStaleProcess([object]$Process, [string]$ProjectRoot, [string]$ElectronExecutable) {
|
||||
$name = [string]$Process.Name
|
||||
$executable = ConvertTo-ComparablePath ([string]$Process.ExecutablePath)
|
||||
$commandLine = [string]$Process.CommandLine
|
||||
|
||||
if ($name -eq "electron.exe") {
|
||||
return $executable -eq (ConvertTo-ComparablePath $ElectronExecutable)
|
||||
}
|
||||
|
||||
if ($name -eq "InputHelper.exe") {
|
||||
$helperPaths = @(
|
||||
(Join-Path $ProjectRoot "native\input-helper\bin\publish\InputHelper.exe"),
|
||||
(Join-Path $ProjectRoot "outputs\dist\win-unpacked\resources\input-helper\InputHelper.exe")
|
||||
)
|
||||
return @($helperPaths | Where-Object { $executable -eq (ConvertTo-ComparablePath $_) }).Count -gt 0
|
||||
}
|
||||
|
||||
if ($name -eq "powershell.exe" -or $name -eq "pwsh.exe") {
|
||||
$legacyHelper = Join-Path $env:APPDATA "genshin-artifact-assistant\input-helper.ps1"
|
||||
return Test-CommandLineContainsPath $commandLine $legacyHelper
|
||||
}
|
||||
|
||||
if ($name -ne "node.exe") { return $false }
|
||||
|
||||
# Node itself is shared by Codex and many other tools. Only the known dev
|
||||
# entrypoints from this repository are safe to classify as stale GAA work.
|
||||
$knownDevEntrypoints = @(
|
||||
(Join-Path $ProjectRoot "node_modules\vite\bin\vite.js"),
|
||||
(Join-Path $ProjectRoot "node_modules\concurrently\dist\bin\concurrently.js"),
|
||||
(Join-Path $ProjectRoot "node_modules\wait-on\bin\wait-on"),
|
||||
(Join-Path $ProjectRoot "node_modules\cross-env\src\bin\cross-env.js")
|
||||
)
|
||||
return @($knownDevEntrypoints | Where-Object { Test-CommandLineContainsPath $commandLine $_ }).Count -gt 0
|
||||
}
|
||||
|
||||
if ($SelfTest) {
|
||||
$cases = @(
|
||||
@{ Name = "project electron"; Expected = $true; Process = [pscustomobject]@{ Name = "electron.exe"; ExecutablePath = $electronPath; CommandLine = "`"$electronPath`" ." } },
|
||||
@{ Name = "other electron"; Expected = $false; Process = [pscustomobject]@{ Name = "electron.exe"; ExecutablePath = "C:\Other\electron.exe"; CommandLine = "" } },
|
||||
@{ Name = "project vite"; Expected = $true; Process = [pscustomobject]@{ Name = "node.exe"; ExecutablePath = "C:\Program Files\nodejs\node.exe"; CommandLine = "node `"$(Join-Path $project 'node_modules\vite\bin\vite.js')`" --host 127.0.0.1" } },
|
||||
@{ Name = "project concurrently"; Expected = $true; Process = [pscustomobject]@{ Name = "node.exe"; ExecutablePath = "C:\Program Files\nodejs\node.exe"; CommandLine = "node `"$(Join-Path $project 'node_modules\concurrently\dist\bin\concurrently.js')`" -k" } },
|
||||
@{ Name = "Codex CUA working dir"; Expected = $false; Process = [pscustomobject]@{ Name = "node.exe"; ExecutablePath = "C:\Users\vmbao\AppData\Local\OpenAI\Codex\runtimes\cua_node\bin\node.exe"; CommandLine = "node kernel.js --working-dir `"$project`"" } },
|
||||
@{ Name = "unrelated node in repo"; Expected = $false; Process = [pscustomobject]@{ Name = "node.exe"; ExecutablePath = "C:\Program Files\nodejs\node.exe"; CommandLine = "node custom-task.js --cwd `"$project`"" } },
|
||||
@{ Name = "legacy helper"; Expected = $true; Process = [pscustomobject]@{ Name = "powershell.exe"; ExecutablePath = "$env:SystemRoot\System32\WindowsPowerShell\v1.0\powershell.exe"; CommandLine = "powershell -File `"$(Join-Path $env:APPDATA 'genshin-artifact-assistant\input-helper.ps1')`"" } }
|
||||
)
|
||||
$failedCases = @()
|
||||
foreach ($case in $cases) {
|
||||
$actual = Test-GaaStaleProcess $case.Process $project $electronPath
|
||||
if ($actual -ne $case.Expected) { $failedCases += "$($case.Name): expected=$($case.Expected), actual=$actual" }
|
||||
}
|
||||
if ($failedCases.Count -gt 0) {
|
||||
$failedCases | ForEach-Object { Write-Error $_ }
|
||||
throw "$($failedCases.Count) stale-process classifier self-test(s) failed."
|
||||
}
|
||||
Write-Host "Stale-process classifier: $($cases.Count)/$($cases.Count) tests passed."
|
||||
return
|
||||
}
|
||||
|
||||
$killed = 0
|
||||
$candidatePids = @{}
|
||||
|
||||
@@ -37,28 +115,11 @@ try {
|
||||
}
|
||||
|
||||
Get-CimInstance Win32_Process |
|
||||
Where-Object {
|
||||
($_.Name -eq "electron.exe" -and $_.ExecutablePath -eq $electronPath) -or
|
||||
($_.Name -eq "node.exe" -and $_.CommandLine -like "*$project*") -or
|
||||
($_.Name -eq "powershell.exe" -and $_.CommandLine -like "*input-helper.ps1*")
|
||||
} |
|
||||
Where-Object { Test-GaaStaleProcess $_ $project $electronPath } |
|
||||
ForEach-Object {
|
||||
$candidatePids[[int]$_.ProcessId] = $_.Name
|
||||
}
|
||||
|
||||
try {
|
||||
Get-NetTCPConnection -LocalPort $devControlPort -State Listen -ErrorAction Stop |
|
||||
ForEach-Object {
|
||||
if ($_.OwningProcess -gt 0) {
|
||||
$owner = Get-Process -Id $_.OwningProcess -ErrorAction SilentlyContinue
|
||||
$candidatePids[[int]$_.OwningProcess] = if ($owner) { "$($owner.ProcessName) port $devControlPort" } else { "port $devControlPort owner" }
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
# Get-NetTCPConnection can be unavailable on some machines; process matching
|
||||
# above still handles the normal non-elevated path.
|
||||
}
|
||||
|
||||
$failed = 0
|
||||
foreach ($entry in $candidatePids.GetEnumerator()) {
|
||||
Write-Host "Beende alte Instanz: $($entry.Value) (PID $($entry.Key))"
|
||||
|
||||
Reference in New Issue
Block a user