From d2f21036303c9d6fe9846bf9f5e47665338b756d Mon Sep 17 00:00:00 2001 From: Iwan Kelaiah Date: Fri, 18 Sep 2026 19:02:16 +1000 Subject: [PATCH] refactor(cli): split the build pipeline into named phases RunBuild is now a short orchestrator over three nested phases: ParseCommandLine, ExecuteBuild, and RenderAndReport. The phases share the existing locals, so no option or build-state record is threaded, and the single outer try/finally remains the only owner of the option objects. No behavior changes; the CLI suite covers help, exit codes, incremental parity, coverage policy, and source links. Verified: make test (CLI and functional suites) and byte-identical checked-in example output. --- CHANGELOG.md | 3 ++ src/cli/PasWeave.CLI.pas | 99 ++++++++++++++++++++++++---------------- 2 files changed, 63 insertions(+), 39 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f5b771..f6b74af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,9 @@ and this project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.ht macro expansion, custom-option parsing) into `PasWeave.Lazarus.Support`; `PasWeave.Lazarus` now focuses on project and package graph assembly. +- Split the CLI build pipeline into named `ParseCommandLine`, + `ExecuteBuild`, and `RenderAndReport` phases, leaving `RunBuild` as a short + orchestrator with one owner for option objects and build state. ## [0.7.0] - 2026-09-17 diff --git a/src/cli/PasWeave.CLI.pas b/src/cli/PasWeave.CLI.pas index e2b2678..af1e0d9 100644 --- a/src/cli/PasWeave.CLI.pas +++ b/src/cli/PasWeave.CLI.pas @@ -168,6 +168,7 @@ function RunBuild: Integer; OldManifest: TManifest; NewManifest: TManifest; NewPaths: TStringList; + ParseHandled: Boolean; procedure AppendConfigLine(const ALine: string); begin @@ -248,37 +249,8 @@ function RunBuild: Integer; end; end; -begin - SourcePath := ''; - OutputPath := 'build/docs'; - ProjectName := ''; - ProjectNameExplicit := False; - BuildMode := ''; - Verbose := False; - FailureSeverity := dsError; - HasMinimumCoverage := False; - MinimumCoverage := 0; - RepositoryURL := ''; - SourceLinkTemplate := ''; - ProjectMark := ''; - ThemeAccent := ''; - ThemeAccentAlt := ''; - ThemeFont := ''; - HasProjectMark := False; - HasThemeAccent := False; - HasThemeAccentAlt := False; - HasThemeFont := False; - CleanBuild := False; - SkipBuild := False; - Project := nil; - OldManifest := nil; - StartTick := MonotonicMilliseconds; - CommentStyles := DefaultDocumentationCommentStyles; - DiscoveryOptions := TSourceDiscoveryOptions.Create; - CompilerOptions := TCompilerOptions.Create; - PackagePaths := TStringList.Create; - LazarusConfiguration := nil; - try + procedure ParseCommandLine; + begin I := 2; while I <= ParamCount do begin @@ -489,7 +461,8 @@ function RunBuild: Integer; else if (ParamStr(I) = '--help') or (ParamStr(I) = '-h') then begin PrintUsage; - Exit(0); + ParseHandled := True; + Exit; end else if (Length(ParamStr(I)) > 0) and (ParamStr(I)[1] = '-') then raise EPasWeaveInputError.CreateFmt('unknown option: %s', [ParamStr(I)]) @@ -499,7 +472,12 @@ function RunBuild: Integer; raise EPasWeaveInputError.Create('only one source path may be supplied'); Inc(I); end; + end; + procedure ExecuteBuild; + var + I: Integer; + begin if SourcePath = '' then raise EPasWeaveInputError.Create('missing unit or source directory'); { Validate before fingerprinting so a typo reports a clean input error @@ -624,10 +602,12 @@ function RunBuild: Integer; CommentStyles, DiscoveryOptions, CompilerOptions); SamplePeakHeap; end; + end; - if SkipBuild then - Exit; - + function RenderAndReport: Integer; + var + I: Integer; + begin if not TryConfigureSourceLinks(Project, RepositoryURL, SourceLinkTemplate, SourceLinkError) then raise EPasWeaveInputError.Create(SourceLinkError); @@ -704,6 +684,47 @@ function RunBuild: Integer; Result := 1 else Result := 0; + end; + +begin + SourcePath := ''; + OutputPath := 'build/docs'; + ProjectName := ''; + ProjectNameExplicit := False; + BuildMode := ''; + Verbose := False; + FailureSeverity := dsError; + HasMinimumCoverage := False; + MinimumCoverage := 0; + RepositoryURL := ''; + SourceLinkTemplate := ''; + ProjectMark := ''; + ThemeAccent := ''; + ThemeAccentAlt := ''; + ThemeFont := ''; + HasProjectMark := False; + HasThemeAccent := False; + HasThemeAccentAlt := False; + HasThemeFont := False; + CleanBuild := False; + SkipBuild := False; + Project := nil; + OldManifest := nil; + StartTick := MonotonicMilliseconds; + CommentStyles := DefaultDocumentationCommentStyles; + DiscoveryOptions := TSourceDiscoveryOptions.Create; + CompilerOptions := TCompilerOptions.Create; + PackagePaths := TStringList.Create; + LazarusConfiguration := nil; + ParseHandled := False; + try + ParseCommandLine; + if ParseHandled then + Exit(0); + ExecuteBuild; + if SkipBuild then + Exit; + Result := RenderAndReport; finally Project.Free; OldManifest.Free; @@ -719,10 +740,10 @@ function RunPasWeave: Integer; try if (ParamCount = 0) or (ParamStr(1) = '--help') or (ParamStr(1) = '-h') then - begin - PrintUsage; - Exit(0); - end; + begin + PrintUsage; + Exit(0); + end; if ParamStr(1) = '--version' then begin WriteLn('PasWeave ', PasWeaveVersion);