Skip to content

Commit a1b0991

Browse files
author
DavidQ
committed
Extends validation runner with additional repo structure checks.
BUILD_PR_LEVEL_10_04_VALIDATION_EXTENSIONS
1 parent 50a609f commit a1b0991

7 files changed

Lines changed: 233 additions & 57 deletions

File tree

docs/dev/CODEX_COMMANDS.md

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,9 @@ MODEL: GPT-5.4
22
REASONING: high
33

44
COMMAND:
5-
- ensure Validate-All.ps1 sets exit codes (0 pass, non-zero fail)
6-
- ensure clear PASS/FAIL output
7-
- add optional pre-commit hook example under .githooks/
8-
- keep validation scripts under scripts/PS/validate/
9-
- do not modify engine/runtime code
10-
- commit format:
11-
description first line
12-
PR name last line
13-
- update roadmap status only
5+
- extend Validate-All.ps1
6+
- add checks:
7+
- required folders exist
8+
- scripts in correct directories
9+
- optional asset structure validation
10+
- ensure failures return non-zero exit

docs/dev/COMMIT_COMMENT.txt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1-
Harden Validate-All exit-code behavior, keep clear PASS/FAIL summaries, and add an optional pre-commit hook example under .githooks.
2-
BUILD_PR_LEVEL_10_03_VALIDATION_INTEGRATION
1+
Extends validation runner with additional repo structure checks.
2+
3+
BUILD_PR_LEVEL_10_04_VALIDATION_EXTENSIONS

docs/dev/NEXT_COMMAND.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
BUILD_PR_LEVEL_10_04_VALIDATION_EXTENSIONS
1+
BUILD_PR_LEVEL_10_05_ASSET_STRUCTURE_VALIDATION
Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1 @@
1-
BUILD_PR_LEVEL_10_03_VALIDATION_INTEGRATION
2-
3-
Scope:
4-
- Validation-lane changes only.
5-
- No engine/runtime/tool code touched.
6-
7-
Implemented:
8-
- Updated `scripts/PS/validate/Validate-All.ps1`:
9-
- explicit `0` exit on PASS
10-
- non-zero exit on failure
11-
- clear PASS/FAIL summary output
12-
- guarded error path with failure summary and reason
13-
- Added optional pre-commit hook example:
14-
- `.githooks/pre-commit.example.ps1`
15-
- calls `scripts/PS/validate/Validate-All.ps1`
16-
- blocks commit on validation failure
17-
18-
Constraints:
19-
- Validation scripts remain under `scripts/PS/validate/`.
20-
- Deployment, engine, and runtime behavior were not modified.
1+
Adds additional validation checks.
Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
[x] `scripts/PS/validate/Validate-All.ps1` runs successfully in repo
2-
[x] PASS path returns exit code `0`
3-
[x] failure simulation returns non-zero exit code
4-
[x] clear PASS/FAIL summary output is present
5-
[x] optional `.githooks/pre-commit.example.ps1` calls `Validate-All.ps1`
6-
[x] roadmap updated with status-only change
1+
[ ] run validation
2+
[ ] break folder structure → fails
3+
[ ] restore → passes
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# BUILD_PR — LEVEL 10_04 — VALIDATION EXTENSIONS
2+
3+
## Objective
4+
Extend validation to include:
5+
- missing required folders
6+
- invalid script locations
7+
- optional asset structure checks
8+
9+
## What to Execute
10+
scripts/PS/validate/Validate-All.ps1
11+
12+
## Expected
13+
- Additional validation checks run
14+
- Failures clearly reported

scripts/PS/validate/Validate-All.ps1

Lines changed: 205 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,225 @@
11
[CmdletBinding()]
22
param(
3-
[switch]$Json
3+
[switch]$Json,
4+
[switch]$ValidateAssetStructure
45
)
56

67
Set-StrictMode -Version Latest
78
$ErrorActionPreference = "Stop"
89

9-
$validatorPath = Join-Path $PSScriptRoot "Validate-ScriptStructure.ps1"
10-
if (-not (Test-Path -LiteralPath $validatorPath)) {
11-
throw "Missing validation entrypoint: $validatorPath"
10+
function Get-RepoRoot {
11+
return [System.IO.Path]::GetFullPath((Join-Path $PSScriptRoot "..\..\.."))
1212
}
1313

14-
try {
14+
function New-ValidationResult {
15+
param(
16+
[Parameter(Mandatory = $true)]
17+
[string]$Check,
18+
[Parameter(Mandatory = $true)]
19+
[bool]$Passed,
20+
[Parameter(Mandatory = $true)]
21+
[string]$Details,
22+
[object]$Data
23+
)
24+
25+
return [pscustomobject]@{
26+
check = $Check
27+
passed = $Passed
28+
details = $Details
29+
data = $Data
30+
}
31+
}
32+
33+
function Test-RequiredFolders {
34+
param(
35+
[Parameter(Mandatory = $true)]
36+
[string]$RepoRoot
37+
)
38+
39+
$required = @(
40+
"scripts\PS",
41+
"scripts\PS\codex",
42+
"scripts\PS\deploy",
43+
"scripts\PS\validate"
44+
)
45+
46+
$missing = @()
47+
foreach ($relativePath in $required) {
48+
$fullPath = Join-Path $RepoRoot $relativePath
49+
if (-not (Test-Path -LiteralPath $fullPath)) {
50+
$missing += $relativePath
51+
}
52+
}
53+
54+
if ($missing.Count -eq 0) {
55+
return New-ValidationResult -Check "requiredFolders" -Passed $true -Details "All required folders are present." -Data ([pscustomobject]@{
56+
required = $required
57+
missing = @()
58+
})
59+
}
60+
61+
return New-ValidationResult -Check "requiredFolders" -Passed $false -Details "Missing required folders: $($missing -join ', ')" -Data ([pscustomobject]@{
62+
required = $required
63+
missing = $missing
64+
})
65+
}
66+
67+
function Test-ScriptStructureContract {
68+
param(
69+
[Parameter(Mandatory = $true)]
70+
[string]$ValidatorPath
71+
)
72+
73+
if (-not (Test-Path -LiteralPath $ValidatorPath)) {
74+
return New-ValidationResult -Check "scriptStructure" -Passed $false -Details "Missing validation entrypoint: $ValidatorPath" -Data $null
75+
}
76+
1577
$global:LASTEXITCODE = 0
78+
$raw = & $ValidatorPath -Json
79+
$exitCode = if ($null -eq $LASTEXITCODE) { 0 } else { [int]$LASTEXITCODE }
80+
81+
$jsonText = ($raw | Out-String).Trim()
82+
if ([string]::IsNullOrWhiteSpace($jsonText)) {
83+
return New-ValidationResult -Check "scriptStructure" -Passed $false -Details "Validate-ScriptStructure produced no JSON output." -Data $null
84+
}
85+
86+
$parsed = $null
87+
try {
88+
$parsed = $jsonText | ConvertFrom-Json
89+
}
90+
catch {
91+
return New-ValidationResult -Check "scriptStructure" -Passed $false -Details "Validate-ScriptStructure JSON parsing failed." -Data ([pscustomobject]@{
92+
exitCode = $exitCode
93+
raw = $jsonText
94+
})
95+
}
96+
97+
$passed = $exitCode -eq 0 -and $parsed.valid -eq $true
98+
$issueCount = if ($null -ne $parsed.issues) { @($parsed.issues).Count } else { 0 }
99+
$details = if ($passed) {
100+
"Script structure validation passed."
101+
}
102+
else {
103+
"Script structure validation failed with $issueCount issue(s)."
104+
}
105+
106+
return New-ValidationResult -Check "scriptStructure" -Passed $passed -Details $details -Data ([pscustomobject]@{
107+
exitCode = $exitCode
108+
issueCount = $issueCount
109+
issues = $parsed.issues
110+
})
111+
}
112+
113+
function Test-OptionalAssetStructure {
114+
param(
115+
[Parameter(Mandatory = $true)]
116+
[string]$RepoRoot
117+
)
118+
119+
$gamesRoot = Join-Path $RepoRoot "games"
120+
if (-not (Test-Path -LiteralPath $gamesRoot)) {
121+
return New-ValidationResult -Check "assetStructure" -Passed $false -Details "Missing games root: games/" -Data $null
122+
}
123+
124+
$domains = @("sprites", "tilemaps", "parallax", "vectors")
125+
$issues = New-Object System.Collections.Generic.List[string]
126+
$checkedGames = New-Object System.Collections.Generic.List[string]
127+
$checkedDomains = 0
128+
129+
foreach ($gameDir in (Get-ChildItem -LiteralPath $gamesRoot -Directory -ErrorAction SilentlyContinue)) {
130+
$assetsRoot = Join-Path $gameDir.FullName "assets"
131+
if (-not (Test-Path -LiteralPath $assetsRoot)) {
132+
continue
133+
}
134+
135+
$checkedGames.Add($gameDir.Name)
136+
foreach ($domain in $domains) {
137+
$domainRoot = Join-Path $assetsRoot $domain
138+
if (-not (Test-Path -LiteralPath $domainRoot -PathType Container)) {
139+
continue
140+
}
141+
142+
$checkedDomains += 1
143+
$dataRoot = Join-Path $domainRoot "data"
144+
if (-not (Test-Path -LiteralPath $dataRoot -PathType Container)) {
145+
$issues.Add("Missing data folder for $($gameDir.Name)/assets/$domain (expected: games/$($gameDir.Name)/assets/$domain/data)")
146+
}
147+
}
148+
}
149+
150+
$passed = $issues.Count -eq 0
151+
$details = if ($passed) {
152+
if ($checkedDomains -eq 0) {
153+
"Asset structure check passed. No active domain folders were found to validate."
154+
}
155+
else {
156+
"Asset structure check passed for $checkedDomains domain folder(s)."
157+
}
158+
}
159+
else {
160+
"Asset structure check failed with $($issues.Count) issue(s)."
161+
}
162+
163+
return New-ValidationResult -Check "assetStructure" -Passed $passed -Details $details -Data ([pscustomobject]@{
164+
checkedGames = @($checkedGames)
165+
checkedDomainCount = $checkedDomains
166+
issues = @($issues)
167+
})
168+
}
169+
170+
$validatorPath = Join-Path $PSScriptRoot "Validate-ScriptStructure.ps1"
171+
$repoRoot = Get-RepoRoot
172+
173+
try {
174+
$results = New-Object System.Collections.ArrayList
175+
176+
[void]$results.Add((Test-RequiredFolders -RepoRoot $repoRoot))
177+
[void]$results.Add((Test-ScriptStructureContract -ValidatorPath $validatorPath))
178+
179+
if ($ValidateAssetStructure.IsPresent) {
180+
[void]$results.Add((Test-OptionalAssetStructure -RepoRoot $repoRoot))
181+
}
182+
183+
$failed = @($results | Where-Object { -not $_.passed })
184+
$summary = if ($failed.Count -eq 0) { "PASS" } else { "FAIL" }
185+
$output = [pscustomobject]@{
186+
schema = "html-js-gaming.validate-all"
187+
version = 1
188+
summary = $summary
189+
checkCount = @($results).Count
190+
failedCount = $failed.Count
191+
validateAssetStructure = $ValidateAssetStructure.IsPresent
192+
results = @($results)
193+
}
194+
16195
if ($Json.IsPresent) {
17-
& $validatorPath -Json
196+
$output | ConvertTo-Json -Depth 30
18197
}
19198
else {
20-
& $validatorPath
199+
foreach ($result in $results) {
200+
$status = if ($result.passed) { "PASS" } else { "FAIL" }
201+
Write-Host "[$status] $($result.check): $($result.details)"
202+
$issues = @()
203+
if ($null -ne $result.data -and ($result.data.PSObject.Properties.Name -contains "issues")) {
204+
$issues = @($result.data.issues)
205+
}
206+
if (-not $result.passed -and $issues.Count -gt 0) {
207+
foreach ($issue in $issues) {
208+
Write-Host " - $issue"
209+
}
210+
}
211+
}
212+
Write-Host "Validate-All summary: $summary"
21213
}
214+
215+
if ($failed.Count -gt 0) {
216+
exit 1
217+
}
218+
219+
exit 0
22220
}
23221
catch {
24222
Write-Host "Validate-All summary: FAIL"
25223
Write-Host "Reason: $($_.Exception.Message)"
26224
exit 1
27225
}
28-
29-
$validatorExitCode = if ($null -eq $LASTEXITCODE) { 0 } else { [int]$LASTEXITCODE }
30-
$summary = if ($validatorExitCode -eq 0) { "PASS" } else { "FAIL" }
31-
if (-not $Json.IsPresent) {
32-
Write-Host "Validate-All summary: $summary"
33-
}
34-
35-
if ($validatorExitCode -ne 0) {
36-
exit $validatorExitCode
37-
}
38-
39-
exit 0

0 commit comments

Comments
 (0)