From e0c79e0dc0dea1d4b4e95e94dad95319e5648bf8 Mon Sep 17 00:00:00 2001 From: master <> Date: Mon, 9 Mar 2026 07:53:08 +0200 Subject: [PATCH] fix(tools): improve build script discovery and update Verifier to System.CommandLine v8+ Build script: - Add Get-RepoRelativePath() helper for cross-platform path handling - Exclude node_modules and bin/obj from solution discovery Verifier: - Replace deprecated SetHandler with SetAction handler pattern - Use GetRequiredValue/GetValue instead of GetValueForOption - Replace SetDefaultValue with DefaultValueFactory property - Remove CommandLineBuilder wrapper (built into framework now) Co-Authored-By: Claude Opus 4.6 --- scripts/build-all-solutions.ps1 | 25 ++++- src/Tools/StellaOps.Verifier/Program.cs | 91 +++++++++---------- .../StellaOps.Verifier.csproj | 22 +++-- .../StellaOps.Verifier.Tests.csproj | 6 +- 4 files changed, 82 insertions(+), 62 deletions(-) diff --git a/scripts/build-all-solutions.ps1 b/scripts/build-all-solutions.ps1 index b0d1b0cd0..9347f571a 100644 --- a/scripts/build-all-solutions.ps1 +++ b/scripts/build-all-solutions.ps1 @@ -31,8 +31,29 @@ $ErrorActionPreference = 'Continue' $repoRoot = Split-Path -Parent $PSScriptRoot $srcDir = Join-Path $repoRoot 'src' +function Get-RepoRelativePath { + param( + [Parameter(Mandatory = $true)] + [string]$Root, + [Parameter(Mandatory = $true)] + [string]$Path + ) + + $normalizedRoot = [System.IO.Path]::GetFullPath($Root).TrimEnd('\', '/') + $normalizedPath = [System.IO.Path]::GetFullPath($Path) + + if ($normalizedPath.StartsWith($normalizedRoot, [System.StringComparison]::OrdinalIgnoreCase)) { + return $normalizedPath.Substring($normalizedRoot.Length).TrimStart('\', '/') + } + + return $normalizedPath +} + $solutions = Get-ChildItem -Path $srcDir -Filter '*.sln' -Recurse | - Where-Object { $_.Name -ne 'StellaOps.sln' } | + Where-Object { + $_.Name -ne 'StellaOps.sln' -and + $_.FullName -notmatch '[\\/](node_modules|bin|obj)[\\/]' + } | Sort-Object FullName if ($solutions.Count -eq 0) { @@ -50,7 +71,7 @@ $testFail = @() $testSkipped = @() foreach ($sln in $solutions) { - $rel = [System.IO.Path]::GetRelativePath($repoRoot, $sln.FullName) + $rel = Get-RepoRelativePath -Root $repoRoot -Path $sln.FullName Write-Host "--- BUILD: $rel ---" -ForegroundColor Yellow dotnet build $sln.FullName --configuration $Configuration --nologo -v quiet diff --git a/src/Tools/StellaOps.Verifier/Program.cs b/src/Tools/StellaOps.Verifier/Program.cs index d68c947d2..965c1df93 100644 --- a/src/Tools/StellaOps.Verifier/Program.cs +++ b/src/Tools/StellaOps.Verifier/Program.cs @@ -13,13 +13,11 @@ using StellaOps.Verifier; using System.CommandLine; -using System.CommandLine.Builder; -using System.CommandLine.Parsing; var bundleOption = new Option("--bundle", ["-b"]) { Description = "Path to the evidence bundle to verify", - IsRequired = true + Required = true }; var trustedKeysOption = new Option("--trusted-keys", ["-k"]) @@ -39,33 +37,33 @@ var outputOption = new Option("--output", ["-o"]) var formatOption = new Option("--format", ["-f"]) { - Description = "Report output format" + Description = "Report output format", + DefaultValueFactory = _ => ReportFormat.Markdown }; -formatOption.SetDefaultValue(ReportFormat.Markdown); var verifySignaturesOption = new Option("--verify-signatures") { - Description = "Verify bundle manifest signatures" + Description = "Verify bundle manifest signatures", + DefaultValueFactory = _ => true }; -verifySignaturesOption.SetDefaultValue(true); var verifyTimestampsOption = new Option("--verify-timestamps") { - Description = "Verify RFC 3161 timestamps" + Description = "Verify RFC 3161 timestamps", + DefaultValueFactory = _ => true }; -verifyTimestampsOption.SetDefaultValue(true); var verifyDigestsOption = new Option("--verify-digests") { - Description = "Verify blob digests" + Description = "Verify blob digests", + DefaultValueFactory = _ => true }; -verifyDigestsOption.SetDefaultValue(true); var verifyPairsOption = new Option("--verify-pairs") { - Description = "Verify pair artifacts (SBOM, delta-sig)" + Description = "Verify pair artifacts (SBOM, delta-sig)", + DefaultValueFactory = _ => true }; -verifyPairsOption.SetDefaultValue(true); var quietOption = new Option("--quiet", ["-q"]) { @@ -92,19 +90,19 @@ var verifyCommand = new Command("verify", "Verify an evidence bundle") verboseOption }; -verifyCommand.SetHandler(async (context) => +verifyCommand.SetAction(async (parseResult, ct) => { - var bundle = context.ParseResult.GetValueForOption(bundleOption)!; - var trustedKeys = context.ParseResult.GetValueForOption(trustedKeysOption); - var trustProfile = context.ParseResult.GetValueForOption(trustProfileOption); - var output = context.ParseResult.GetValueForOption(outputOption); - var format = context.ParseResult.GetValueForOption(formatOption); - var verifySignatures = context.ParseResult.GetValueForOption(verifySignaturesOption); - var verifyTimestamps = context.ParseResult.GetValueForOption(verifyTimestampsOption); - var verifyDigests = context.ParseResult.GetValueForOption(verifyDigestsOption); - var verifyPairs = context.ParseResult.GetValueForOption(verifyPairsOption); - var quiet = context.ParseResult.GetValueForOption(quietOption); - var verbose = context.ParseResult.GetValueForOption(verboseOption); + var bundle = parseResult.GetRequiredValue(bundleOption); + var trustedKeys = parseResult.GetValue(trustedKeysOption); + var trustProfile = parseResult.GetValue(trustProfileOption); + var output = parseResult.GetValue(outputOption); + var format = parseResult.GetValue(formatOption); + var verifySignatures = parseResult.GetValue(verifySignaturesOption); + var verifyTimestamps = parseResult.GetValue(verifyTimestampsOption); + var verifyDigests = parseResult.GetValue(verifyDigestsOption); + var verifyPairs = parseResult.GetValue(verifyPairsOption); + var quiet = parseResult.GetValue(quietOption); + var verbose = parseResult.GetValue(verboseOption); var options = new VerifierOptions { @@ -122,8 +120,7 @@ verifyCommand.SetHandler(async (context) => }; var verifier = new BundleVerifier(); - var exitCode = await verifier.VerifyAsync(options, context.GetCancellationToken()); - context.ExitCode = exitCode; + return await verifier.VerifyAsync(options, ct); }); var infoCommand = new Command("info", "Display bundle information without verification") @@ -133,19 +130,18 @@ var infoCommand = new Command("info", "Display bundle information without verifi quietOption }; -infoCommand.SetHandler(async (context) => +infoCommand.SetAction(async (parseResult, ct) => { - var bundle = context.ParseResult.GetValueForOption(bundleOption)!; - var format = context.ParseResult.GetValueForOption(formatOption); - var quiet = context.ParseResult.GetValueForOption(quietOption); + var bundle = parseResult.GetRequiredValue(bundleOption); + var format = parseResult.GetValue(formatOption); + var quiet = parseResult.GetValue(quietOption); var verifier = new BundleVerifier(); - var exitCode = await verifier.ShowInfoAsync( + return await verifier.ShowInfoAsync( bundle.FullName, format, quiet, - context.GetCancellationToken()); - context.ExitCode = exitCode; + ct); }); var rootCommand = new RootCommand("Stella Ops Bundle Verifier - Offline evidence bundle verification") @@ -154,16 +150,17 @@ var rootCommand = new RootCommand("Stella Ops Bundle Verifier - Offline evidence infoCommand }; -// Add version option -rootCommand.AddOption(new Option("--version", "Show version information")); - -var parser = new CommandLineBuilder(rootCommand) - .UseDefaults() - .UseExceptionHandler((ex, context) => - { - Console.Error.WriteLine($"Error: {ex.Message}"); - context.ExitCode = 2; - }) - .Build(); - -return await parser.InvokeAsync(args); +try +{ + return await rootCommand.Parse(args).InvokeAsync(); +} +catch (OperationCanceledException) +{ + Console.Error.WriteLine("Verification cancelled."); + return 2; +} +catch (Exception ex) +{ + Console.Error.WriteLine($"Error: {ex.Message}"); + return 2; +} diff --git a/src/Tools/StellaOps.Verifier/StellaOps.Verifier.csproj b/src/Tools/StellaOps.Verifier/StellaOps.Verifier.csproj index 3ea54df62..4e361b06e 100644 --- a/src/Tools/StellaOps.Verifier/StellaOps.Verifier.csproj +++ b/src/Tools/StellaOps.Verifier/StellaOps.Verifier.csproj @@ -20,14 +20,6 @@ Stella Ops Bundle Verifier Standalone verifier for Stella Ops evidence bundles - - true - true - true - partial - true - true - true false @@ -37,6 +29,14 @@ false + + true + true + partial + true + true + + win-x64;linux-x64;linux-musl-x64;osx-x64;osx-arm64 @@ -46,6 +46,12 @@ + + + + + + diff --git a/src/Tools/StellaOps.Verifier/__Tests/StellaOps.Verifier.Tests/StellaOps.Verifier.Tests.csproj b/src/Tools/StellaOps.Verifier/__Tests/StellaOps.Verifier.Tests/StellaOps.Verifier.Tests.csproj index 76d6547b4..00646f8f7 100644 --- a/src/Tools/StellaOps.Verifier/__Tests/StellaOps.Verifier.Tests/StellaOps.Verifier.Tests.csproj +++ b/src/Tools/StellaOps.Verifier/__Tests/StellaOps.Verifier.Tests/StellaOps.Verifier.Tests.csproj @@ -13,16 +13,12 @@ enable false true + false - - - runtime; build; native; contentfiles; analyzers; buildtransitive - all - runtime; build; native; contentfiles; analyzers; buildtransitive all