Add phase-aware CLI argument escape hatch - #3845
Conversation
…ments # Conflicts: # src/ModularPipelines/Context/CommandLineBuilder.cs # src/ModularPipelines/Options/CommandLineToolOptions.cs
Code reviewReviewed the phase-aware 1. A literal
|
|
Addressed both findings at 7c2f9d4: literal -- is now rejected in every non-legacy additional-argument phase, with regression coverage across EarlyOperand/Normal/Passthrough/Terminal; the legacy phase ordinal is centralized beside CommandLinePhase and shared by both builders. After merging current main: CommandLineBuilderTests 59/59, core Release build 0 warnings/errors. @claude review |
|
Required Ubuntu pipeline failed on an unrelated timing-sensitive Flush_CancellationInterruptsRenderGateWait test while this PR's focused validation passed. The full workflow completed, so I triggered the one allowed failed-job rerun. |
|
The single allowed rerun (attempt 2) failed in two different unrelated timing-sensitive core tests: |
|
The single failed-job rerun also failed on the prior base, so I merged current main at 952ca4d to trigger a fresh full workflow. CommandLineBuilderTests pass 59/59 after the refresh. |
There was a problem hiding this comment.
Code review (re-review)
Re-reviewed after the fixes pushed at 7c2f9d4 / 952ca4d5e0. Both issues from the prior review are verifiably resolved:
- Literal
--outside the legacy phase —ValidateAdditionalArguments(CommandLineBuilder.cs:260-274) now rejects anyAdditionalCommandLineArgumentwhoseValue == "--"unlessPhase == CommandLinePhaseCompatibility.LegacyEndOfOptions, and the reverse (legacy phase requires the value to be--). The newBuild_Rejects_Additional_Terminator_Outside_Legacy_Phasetest exercises all four non-legacy phases. - Duplicated
LegacyEndOfOptionsPhaseconstant — hoisted intoCommandLinePhaseCompatibility.LegacyEndOfOptionsinAttributes/CommandLinePhase.cs:37-40, and bothCommandLineBuilder.csandCommandArgumentBuilder.csnow reference the single shared constant instead of each declaring their own copy.
Additional verification this pass
I traced a scenario the fix doesn't explicitly test: combining the new AdditionalArguments legacy -- with an existing legacy-phase model property (the kind emitted by older generated packages, e.g. the TestLegacyEndOfOptionsOptions fixture's [CliFlag("--", Phase = (CommandLinePhase)2)]). Worth checking because that's a second, independent source of a literal -- that isn't covered by the "at most one legacy marker in AdditionalArguments" count check. Traced it through BuildNonTerminalArguments → CommandArgumentBuilder.BuildArguments → ValidateOptionTerminatorOrdering: because BuildNonTerminalArguments sets emittedOptionTerminator = true from the additional argument before calling into CommandArgumentBuilder.BuildArguments for that phase, ValidateOptionTerminatorOrdering's pre-existing guard (optionTerminatorAlreadyEmitted && renderedOptions.Length > 0 → throw) correctly rejects the combination rather than silently emitting two -- tokens. No gap here — the existing terminator-ordering validation generalizes correctly to the new argument source.
Design note (non-blocking)
CommandLineBuilder.cs was already large before this PR and is now ~820 lines mixing several concerns: phase-aware argument assembly, manual-option extraction/matching (short-option cluster parsing, attached-value parsing, etc.), and terminator validation. This PR's addition (BuildNonTerminalArguments, ValidateAdditionalArguments, GetAdditionalArguments) is consistent with the file's existing static-method style, so it's not something to fix in this PR — but if AdditionalArguments grows more validation rules over time, pulling the ValidateAdditionalArguments/GetAdditionalArguments pair into a small dedicated internal helper (mirroring how ICommandArgumentBuilder is already split out) would keep CommandLineBuilder focused on orchestration rather than also owning validation-rule details for each argument source. Just a maintainability observation, not required for merge.
Verdict
The phase-aware AdditionalArguments escape hatch is well-scoped, the terminator-safety invariants are consistently enforced across all the ways -- can now enter the command line (structured arguments, manual Arguments, and now AdditionalArguments), and the new tests cover the placement/scope/rejection cases well. No blocking issues found. CI is currently re-running on the latest merge commit (952ca4d) — worth confirming green before merge, but nothing here should require further code changes.
|
CI diagnosis: Ubuntu failed one unrelated core timing test out of 1,904: |
|
Required pipeline attempt 1 ended in the known core-suite hang/exit 2 with no deterministic assertion or compile error. Requested the single failed-job rerun. |
|
@claude review Please re-review the exact current head. Report blocking/actionable findings only. If none exist, state plainly that there are no blocking or actionable findings; omit optional design notes and future-maintainability suggestions. |
|
@claude Please provide a concise current-head merge verdict. The previous review found no blocking issues; please omit non-actionable design-note category headings because the repository merge gate conservatively parses those headings as actionable. No code changes were made for that explicitly non-blocking note. |
|
Refreshed with current main at be99f8e. Merge was clean. Post-refresh validation: CommandLineBuilderTests 59/59, lightweight core Release build 0 warnings/errors. @claude Please review current head and provide a concise merge verdict without restating previously noted non-blocking design observations. |
There was a problem hiding this comment.
Re-reviewed at current head (be99f8eca7). No blocking or actionable findings.
The PR-relevant files (CommandLineBuilder.cs, CommandArgumentBuilder.cs, CommandLinePhase.cs, AdditionalCommandLineArgument.cs, CommandLineToolOptions.cs, the new tests, and the docs) are byte-for-byte identical to 952ca4d5e0, which was already reviewed and cleared — the merges since then (952ca4d5e0 → be99f8eca7) only pulled in unrelated main changes. Both previously-flagged issues (literal -- bypassing terminator tracking outside the legacy phase; the duplicated LegacyEndOfOptionsPhase constant) remain fixed as verified last pass.
Merge verdict: approve on code content. CI on the latest merge commit is still pending at review time — confirm green before merging.
|
Refreshed onto current main after the prior Ubuntu core-suite run hung for 16 minutes and exited 2/134 without a failing-test summary. Validation on 6b4dd63: CommandLineBuilderTests 59/59, ModularPipelines.slnx Release build 0 warnings/errors, and OptionsGenerator solution Release build 0 warnings/errors. |
Code reviewRe-reviewed at current head ( Confirmed via diff that all PR-relevant files ( Merge verdict: approve on code content. CI on the latest merge commit is still in progress at review time — confirm green before merging. |
Summary
AdditionalArgumentsfor unmodeled CLI tokensArgumentsordering and the generated-options escape hatchValidation
CommandLineBuilderTests: 16 passedModularPipelines.slnxRelease build: 0 warnings, 0 errorsCloses #3784