Files
git.stella-ops.org/docs/technical/architecture/scripts/validate-webservice-docs.ps1

104 lines
3.1 KiB
PowerShell

param(
[string[]] $Files = @(
"docs/technical/architecture/port-registry.md",
"docs/technical/architecture/webservice-catalog.md"
)
)
Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"
function Get-RepositoryRoot {
param([string] $Start)
$current = Resolve-Path $Start
while ($null -ne $current) {
if (Test-Path (Join-Path $current "docs")) {
return $current
}
$parent = Split-Path -Parent $current
if ($parent -eq $current) {
break
}
$current = $parent
}
throw "Could not locate repository root from '$Start'."
}
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
$repoRoot = Get-RepositoryRoot -Start $scriptDir
$pathViolations = [System.Collections.Generic.List[string]]::new()
$hostViolations = [System.Collections.Generic.List[string]]::new()
$pathPattern = [regex]'`(?<path>src/[^`]+)`'
$urlPattern = [regex]'https?://(?<host>[A-Za-z0-9.-]+)'
$legacyHostPattern = [regex]'\b(?<host>[a-z0-9.-]+\.stellaops\.local)\b'
foreach ($relativeFile in $Files) {
$normalizedRelative = $relativeFile.Replace('\\', '/').Trim()
$absoluteFile = Join-Path $repoRoot $normalizedRelative
if (-not (Test-Path $absoluteFile)) {
throw "Validation file not found: $normalizedRelative"
}
$lineNumber = 0
foreach ($line in Get-Content $absoluteFile) {
$lineNumber++
foreach ($match in $pathPattern.Matches($line)) {
$pathValue = $match.Groups['path'].Value.Trim()
$absolutePath = Join-Path $repoRoot ($pathValue.Replace('/', [IO.Path]::DirectorySeparatorChar))
if (-not (Test-Path $absolutePath)) {
$pathViolations.Add("${normalizedRelative}:$lineNumber unresolved path '$pathValue'")
}
}
foreach ($match in $urlPattern.Matches($line)) {
$hostValue = $match.Groups['host'].Value.ToLowerInvariant()
if ($hostValue -eq "localhost") {
continue
}
if ($hostValue.StartsWith("127.")) {
continue
}
if ($hostValue -eq "stella-ops.local" -or $hostValue.EndsWith(".stella-ops.local")) {
continue
}
$hostViolations.Add("${normalizedRelative}:$lineNumber non-canonical runtime host '$hostValue'")
}
foreach ($match in $legacyHostPattern.Matches($line)) {
$hostValue = $match.Groups['host'].Value.ToLowerInvariant()
if ($hostValue -eq "hosts.stellaops.local") {
continue
}
$hostViolations.Add("${normalizedRelative}:$lineNumber forbidden legacy hostname '$hostValue' (expected .stella-ops.local)")
}
}
}
if ($pathViolations.Count -eq 0 -and $hostViolations.Count -eq 0) {
Write-Output "PASS validate-webservice-docs: files=$($Files.Count), pathViolations=0, hostViolations=0"
exit 0
}
Write-Output "FAIL validate-webservice-docs"
foreach ($violation in $pathViolations) {
Write-Output "PATH: $violation"
}
foreach ($violation in $hostViolations) {
Write-Output "HOST: $violation"
}
exit 1