Skip to content

fix(generator): scope gcloud argument group descriptions - #4870

Merged
thomhurst merged 7 commits into
mainfrom
issue-4799-gcloud-group-descriptions
Sep 14, 2026
Merged

thomhurst merged 7 commits into
mainfrom
issue-4799-gcloud-group-descriptions

Conversation

@thomhurst

@thomhurst thomhurst commented Sep 13, 2026

Copy link
Copy Markdown
Owner

Gcloud group introductions and unrecognized flag headers could leak into unrelated option descriptions and type inference. Hive/Iceberg migration context appeared on --async; storage diagnostic paths and numeric counts incorrectly became enums from adjacent transfer-strategy flags.

Plain group introductions at their flags' indentation now keep sibling context separate. The parser treats default annotations as display text, including enum representations containing spaces, so download/upload headers remain declarations. Their descriptions and enum values stay with their own options. #4926 incorporated full authoritative output from source 0f63058, including clean LogsPath/ProcessCount/ThreadCount values and separate DownloadType/UploadType properties.

The latest review follow-up preserves classified argument groups across narrative asides. After moving to the containing group, indentation alone can start a sibling only when that group has no classification. Explicit headings can still start a sibling. This preserves AtMostOne, AtLeastOne, Alternative, and Resource membership without regressing plain Hive/Iceberg sections.

Regression coverage includes nested/sibling groups, narrative asides, explicit replacement headings, exact descriptions, option types, and generated XML documentation. Captured Linux SDK 584.0.0 migration help and Windows SDK 550.0.0 storage diagnostic help remain unchanged.

Validation at 160e06d:

  • All 1,437 generator tests pass, including all 47 argument-group tests. Four new narrative-aside cases fail before the fix.
  • Release generator solution build has zero warnings/errors with SDK 10.0.401.
  • Scoped severity-info formatting verification and git diff --check pass under unchanged 10-minute/2-GB guards. Earlier package API checks passed; this follow-up changes no public API declarations.
  • [Automated] Update gcloud CLI Options #4926 passed generated Google integration checks before merging. The latest parser follow-up still needs final-source output and a subsequent CI/review cycle.

Full Gcloud generation from this exact commit: https://github.com/thomhurst/ModularPipelines/actions/runs/34824921392. Source fingerprint: 8b78e4fe7cbe37504736e6adc1a6cd6c63331f0df244f57ce30804d384bd369f. Auto-merge and coverage-shrinkage approval are disabled. No generated options or baselines were hand-edited.

Refs #4799. Final-source output remains outstanding.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 13, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-14T08:55:43.804855Z 160e06d New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@thomhurst

Copy link
Copy Markdown
Owner Author

Authoritative Linux gcloud generation is queued at https://github.com/thomhurst/ModularPipelines/actions/runs/34771969139. Expected output branch: automated/update-cli-options-gcloud-issue-4799-gcloud-group-descriptions. All 1,354 generator tests pass; generated output and Google integration validation remain required before merge.

@coderabbitai

coderabbitai Bot commented Sep 13, 2026

Copy link
Copy Markdown

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: 6f4d3d68-9b10-41e3-8af1-81cb30c57ec2

📥 Commits

Reviewing files that changed from the base of the PR and between b3c750f and 0f63058.

📒 Files selected for processing (3)
  • tools/ModularPipelines.OptionsGenerator/src/ModularPipelines.OptionsGenerator.Tests/Fixtures/Gcloud/storage-diagnose.txt
  • tools/ModularPipelines.OptionsGenerator/src/ModularPipelines.OptionsGenerator.Tests/Scrapers/Cli/GcloudGroupDescriptionTests.cs
  • tools/ModularPipelines.OptionsGenerator/src/ModularPipelines.OptionsGenerator/Scrapers/Cli/GcloudCliScraper.cs

Included review availability: Your plan provides up to 4 included reviews per hour; 1 remains after this review.


📝 Walkthrough

Walkthrough

The Gcloud parser now detects argument groups from indentation and uses generated regular expressions. Tests cover enum, sibling, same-indentation, nested, and unrelated option parsing. New fixtures document Metastore migration and storage diagnostic commands.

Changes

Gcloud scraper parsing

Layer / File(s) Summary
Indentation-based argument-group detection
tools/ModularPipelines.OptionsGenerator/src/ModularPipelines.OptionsGenerator/Scrapers/Cli/CliArgumentGroupParser.cs
The parser uses prelude and argument indentation to identify root and nested argument groups. Child groups use a collection expression during build.
Generated Gcloud scraper patterns
tools/ModularPipelines.OptionsGenerator/src/ModularPipelines.OptionsGenerator/Scrapers/Cli/GcloudCliScraper.cs
The scraper uses generated regular expressions for sections, subcommands, descriptions, flags, positional arguments, and enum values. Default annotations can contain spaces. Informational path logging is guarded by a log-level check.
Gcloud parsing validation and fixtures
tools/ModularPipelines.OptionsGenerator/src/ModularPipelines.OptionsGenerator.Tests/Scrapers/Cli/GcloudGroupDescriptionTests.cs, tools/ModularPipelines.OptionsGenerator/src/ModularPipelines.OptionsGenerator.Tests/Fixtures/Gcloud/*
Tests cover enum, sibling, same-indentation, nested, and unrelated option parsing. Fixtures document Metastore migration and storage diagnostic commands.

Priority: ⬇️ Low

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Bug fix

Merge Risk: ⚪ Minimal · up to 0f630

No actionable merge-blocking issue is established.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 4.17% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 24 functions across 3 files. (1 skipped: 1… Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: scoping gcloud argument-group descriptions in the generator.
Full details: Docstring Coverage

Explanation

Docstring coverage is 4.17% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 24 functions across 3 files. (1 skipped: 1 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch issue-4799-gcloud-group-descriptions

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

A rabbit reads each line,
The patch grows clear beneath the moon,
Small changes hop in place,
Tests guard the garden path,
Reviews bloom before the dawn.

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown
Contributor

Review

Blocking: the diff does not compile.

In tools/ModularPipelines.OptionsGenerator/src/ModularPipelines.OptionsGenerator/Generators/GeneratorUtils.cs, the CSharpKeywords field was converted from a constructor-initialized HashSet<string> to a collection expression, but the comparer argument was left in as an invalid element:

private static readonly HashSet<string> CSharpKeywords =
[
    with(StringComparer.Ordinal),
    "abstract", "as", "base", ...
];

with(StringComparer.Ordinal) is not valid C# — collection expressions ([...]) have no syntax for passing constructor arguments like a comparer to the target type, and with is only meaningful as an expression's with { ... } clause on records/structs, not as a call. This won't compile under any C# version, so the generator project (and anything depending on it, e.g. the options-generation workflow and its tests) is broken.

Suggested fix: keep the comparer by reverting to object-creation syntax instead of forcing a collection-expression conversion here:

private static readonly HashSet<string> CSharpKeywords = new(StringComparer.Ordinal)
{
    "abstract", "as", "base", ...
};

Collection expressions are a nice simplification when there's no comparer/capacity to pass (see the GetPathSeparatorVariants change a few lines above, which is fine), but here the ordinal comparer is semantically important (case-sensitive keyword matching) and there's no collection-expression equivalent for supplying it — so this particular site isn't a good candidate for the conversion.

Discrepancy with the PR description: the description states "All 32 focused group-parser tests and all 1,354 generator tests pass. Generator solution Release build: zero warnings/errors," but the head commit as checked out does not compile. Please re-verify the build/test run was actually against this commit before merge.


The CliArgumentGroupParser.cs indentation-scoping fix and its new regression tests (GcloudGroupDescriptionTests.cs, sibling-group / nested-group / unrelated-option-type cases) look reasonable and target the described bug (plain-text group intros bleeding into unrelated sibling options) directly. The ConfigureAwait(false) addition to generated service methods and the new ServiceAwaitGenerationTests.cs covering it are correct and consistent with the repo's ConfigureAwait(false) convention for library code. The workflow change to key GENERATED_OPTIONS_BRANCH/PR lookup off the ref name for non-default branches is a sensible way to stop feature-branch regeneration runs from clobbering another branch's automated PR.

Once the CSharpKeywords collection-expression bug is fixed and the build/tests are re-confirmed, this looks close to mergeable — but per the description, authoritative gcloud regeneration and generated-output review are still pending anyway.

@greptile-apps

greptile-apps Bot commented Sep 13, 2026

Copy link
Copy Markdown

Greptile Summary

This PR improves gcloud help parsing so plain-text argument-group introductions remain scoped to their groups and Python-style, multi-word default annotations are recognized correctly.

  • Uses indentation to distinguish group prose from root option documentation.
  • Expands gcloud default annotation parsing without changing captured option value hints.
  • Adds authoritative fixtures and focused regression tests for sibling groups, nested groups, option metadata, and generated documentation.
  • Converts repeated runtime regex construction to source-generated regex methods.

Confidence Score: 5/5

The reviewed source and test changes appear safe to merge once the PR’s separately required authoritative generated-output validation is completed.

No actionable new defect or repository-rule violation was found. The latest regex change preserves option value capture while accepting genuine multi-word default annotations, and the added tests exercise the affected type and description boundaries. Focused tests could not be rerun in this environment because PowerShell is unavailable, but this does not establish a code issue.

Important Files Changed

Filename Overview
tools/ModularPipelines.OptionsGenerator/src/ModularPipelines.OptionsGenerator/Scrapers/Cli/CliArgumentGroupParser.cs Uses prose indentation when constructing argument-group hierarchy so sibling and nested group descriptions do not leak into root options.
tools/ModularPipelines.OptionsGenerator/src/ModularPipelines.OptionsGenerator/Scrapers/Cli/GcloudCliScraper.cs Recognizes multi-word gcloud default annotations and moves equivalent parsing expressions to generated regex methods.
tools/ModularPipelines.OptionsGenerator/src/ModularPipelines.OptionsGenerator.Tests/Scrapers/Cli/GcloudGroupDescriptionTests.cs Adds regression coverage for authoritative same-indentation groups, nested context isolation, enum defaults, and generated XML documentation.
tools/ModularPipelines.OptionsGenerator/src/ModularPipelines.OptionsGenerator.Tests/Fixtures/Gcloud/metastore-services-migrations-start.txt Adds authoritative Linux gcloud help containing sibling Hive and Iceberg group introductions.
tools/ModularPipelines.OptionsGenerator/src/ModularPipelines.OptionsGenerator.Tests/Fixtures/Gcloud/storage-diagnose.txt Adds gcloud help containing Python enum default representations and nested argument groups.

Reviews (5): Last reviewed commit: "fix(generator): parse gcloud enum defaul..." | Re-trigger Greptile

@thomhurst

Copy link
Copy Markdown
Owner Author

The compiler claim in issuecomment-5654919275 is incorrect for this repository: global.json pins SDK 10.0.401 and Directory.Build.props enables LangVersion=preview, which supports comparer-bearing collection expressions. The generator solution compiled locally on 923abaf with zero warnings/errors and all 1,354 tests passed (archived TRX). The same shared source compiled in Linux CI under SDK 10.0.401 at https://github.com/thomhurst/ModularPipelines/actions/runs/34771665246/job/103762311459. No syntax rewrite is needed. Authoritative gcloud generation remains queued at run 34771969139; generated output and integration validation still block merge.

@thomhurst

Copy link
Copy Markdown
Owner Author

Pushed 7e58658 after the final generated-output audit found #4877 still leaking both Hive and Iceberg introductions into Async and unrelated flags. Provenance matched the source, so the original fixture had missed real formatting rather than generation using stale code.

Captured unmodified gcloud metastore services migrations start --help from Linux SDK 584.0.0. Plain headings and their flags have equal indentation. The parser now treats such standalone preludes as group boundaries, preserving the preceding root flags and keeping sibling descriptions separate. The complete fixture checks group membership, exact Async prose, absence of sibling text on HiveCatalog/IcebergCatalog, and generated Async XML documentation. It failed before the fix and passes afterward.

All 33 group-parser tests and all 1,355 generator tests pass; the Release solution build has zero warnings/errors. Scoped formatting and diff checks pass. This also reconfirms that the collection-expression compiler concern in review 5654919275 does not apply to the pinned SDK and preview language configuration. Replacement authoritative generation has been dispatched from 7e58658 with auto-merge and coverage-shrinkage approval disabled. #4877 and this parent remain blocked until corrected output is reviewed and validated.

@github-actions

Copy link
Copy Markdown
Contributor

Code review

Summary: This PR fixes the gcloud argument-group parser so that plain-text group introductions at the same indentation as their flags (e.g. "Configuration for Hive migration.") are recognized as group boundaries, preventing that prose from leaking into sibling/unrelated option descriptions. It adds solid regression coverage (synthetic sibling/nested cases plus an authoritative fixture captured from real gcloud metastore services migrations start --help output), adds ConfigureAwait(false) to generated service-method awaits with matching tests, and scopes the generate-cli-options.yml workflow's generated-PR branch name per source branch so feature-branch regeneration runs stop clobbering another branch's automated PR.

Blocking: GeneratorUtils.cs still does not compile.

CSharpKeywords was converted from an object-initializer HashSet<string> into a collection expression, but a comparer is injected as a fabricated element:

private static readonly HashSet<string> CSharpKeywords =
[
    with(StringComparer.Ordinal),
    "abstract", "as", "base", ...
];

This is unchanged from the previous review of this PR (flagged at commit 923abaf) and is still present at head 7e58658. with(StringComparer.Ordinal) is not valid C# in any language version, including LangVersion=preview (C# collection-expression grammar only allows expression_element and ..spread_element items — there is no argument/comparer syntax for target-typed collection expressions, and the shipped .NET 10 / C# 14 feature set has no such construct). As written, with doesn't resolve to anything in scope, so this is a compile error (CS0103) — the generator project, and everything that depends on it (the options-generation workflow and its own tests, including the new ServiceAwaitGenerationTests.cs and GcloudGroupDescriptionTests.cs added by this very PR), cannot build.

The PR's own comments assert this compiles under the pinned SDK/preview LangVersion and cite a passing local build and CI run, but that claim doesn't hold up against the actual C# grammar, and it doesn't matter which SDK is pinned — no shipped or preview C# version supports comparer arguments inside [...] collection-expression literals. Please revert this one site back to object-creation syntax, which is the only way to supply a non-default comparer here:

private static readonly HashSet<string> CSharpKeywords = new(StringComparer.Ordinal)
{
    "abstract", "as", "base", ...
};

(The GetPathSeparatorVariants collection-expression change a few lines above is fine — it spreads an already-built sequence with [.. ...] rather than trying to smuggle a comparer into the literal, so it isn't affected by this issue.)

Everything else looks solid:

  • CliArgumentGroupParser.cs: tightening the boundary check from < to <= (prelude indentation vs. the first declaration's indentation) correctly captures headings written at the same depth as their flags, which is exactly the real-world gcloud formatting shown in the new metastore-services-migrations-start.txt fixture. The added tests (sibling groups, nested groups with unrelated option types, and the full authoritative fixture) exercise this well.
  • generate-cli-options.yml: computing GENERATED_OPTIONS_BRANCH once per matrix job and consistently using it for both the gh pr list --head lookup and the create-pull-request branch/PR-lookup step is a clean way to isolate feature-branch refresh output; applied identically to both the Linux and Windows jobs.
  • ConfigureAwait(false) on the generated service awaits matches this repo's convention for library code, and the new ServiceAwaitGenerationTests.cs pins the generated output for both required/optional options and top-level/nested services.

No CLAUDE.md violations otherwise: the changes are confined to the generator/scraper's generic logic and its tests (no hand-edited generated option files), consistent with "fix the scraper or generator ... never hand-edit generated options."

Note: I wasn't able to execute a local build/test run in this review environment to get a compiler-verified confirmation of the with(...) failure, but the syntax is unambiguously invalid per the C# collection-expression grammar regardless of toolchain, so this should fail in CI as well once actually compiled.

@thomhurst

thomhurst commented Sep 14, 2026

Copy link
Copy Markdown
Owner Author

The current-head Ubuntu pipeline failed in RunReportOmitsOutputWhenTimedOutEnricherCanRegisterSecretsLater with TimeoutException at the existing outer test guard. Failed job: https://github.com/thomhurst/ModularPipelines/actions/runs/34790257718/job/103813476167. This is the shared RunReportTests guard addressed by #4678, which is currently awaiting CI. No CI rerun was requested; sync the test fix after it lands. This failure does not identify a generator regression.

@thomhurst
thomhurst force-pushed the issue-4799-gcloud-group-descriptions branch from 7e58658 to 629a0d0 Compare September 14, 2026 02:19
@thomhurst

Copy link
Copy Markdown
Owner Author

Pushed the rebase onto main b9e1a0f as 629a0d0. The old Ubuntu job failed only in RunReportOmitsOutputWhenTimedOutEnricherCanRegisterSecretsLater at its outer three-second guard; this branch now includes merged #4678. All 144 RunReportTests pass, as do all 1,396 generator tests. Generator Release build has zero warnings/errors, and scoped severity-info formatting and diff checks pass under the unchanged guard limits.

Range-diff preserves both parser fixes. Main already contains the safe-await template and generated-branch isolation, so the obsolete extra workflow environment overrides were removed. GeneratorUtils is no longer changed by this PR; its comparer-bearing collection expressions compile under the pinned SDK as demonstrated by the successful build and tests. Fresh CI/review will evaluate the new head.

Generation remains blocked by #4644/#4638, matching the existing baseline audit in #4877 comment 5657672069. I verified the orphaned-marker condition and recorded the native #4799 blocked-by #4638 dependency. Another expensive gcloud refresh is deferred until that baseline fix is part of the generation source. Generated files were not edited, and no failed CI was rerun.

@thomhurst
thomhurst deployed to Pull Requests September 14, 2026 02:22 — with GitHub Actions Active

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 629a0d01c1

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +31 to +34
var firstPreludeStartsGroup = StartsArgumentGroup(firstPreludeLines, firstPrelude)
|| firstPreludeIndentation <= declarations[0].Argument.Indentation;
var root = new ArgumentGroupBuilder(
declarations.Min(declaration => declaration.Argument.Indentation),
Math.Min(firstPreludeIndentation, declarations.Min(declaration => declaration.Argument.Indentation)),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Regenerate the affected gcloud options

This parser change is not reflected in the committed generated output: in this commit, src/ModularPipelines.Google/Options/GcloudMetastoreServicesMigrationsStartOptions.Generated.cs still prefixes Async and the other unrelated properties with both the Hive and Iceberg descriptions, so consumers continue to receive the behavior this change is intended to fix. Regenerate and commit the affected gcloud options together with the scraper update, as required for generator changes.

AGENTS.md reference: AGENTS.md:L33-L34

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The baseline prerequisite #4644 is now merged. Rebased onto main 2e2ddab and pushed b3c750f. Authoritative replacement gcloud generation is running at https://github.com/thomhurst/ModularPipelines/actions/runs/34802649779 with auto-merge disabled. Keeping this finding open until generated output is incorporated and validated; the old #4877 output must be refreshed.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The replacement output in #4926 exposed an additional enum-default header defect. Fixed in 0f63058; all 1,432 generator tests pass. Fresh authoritative generation: https://github.com/thomhurst/ModularPipelines/actions/runs/34808204420. Keeping this finding open until corrected generated output is incorporated and validated.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Corrected full output from #4926 is incorporated at cd0f2b1 and passed Google integration checks. Subsequent review identified a separate narrative-aside grouping issue, now fixed in 160e06d with four before-fix failures and all 1,437 generator tests passing. Final-source Gcloud generation: https://github.com/thomhurst/ModularPipelines/actions/runs/34824921392. Keeping this thread open until new output is incorporated and validated.

@thomhurst
thomhurst force-pushed the issue-4799-gcloud-group-descriptions branch from 629a0d0 to b3c750f Compare September 14, 2026 03:27
@thomhurst

Copy link
Copy Markdown
Owner Author

The baseline prerequisite #4638/#4644 has landed. Rebased the unchanged parser patches onto main 2e2ddab (also including #4688 timeout reporting) and pushed b3c750f. Range-diff confirms all four patches are unchanged. The Release generator solution builds with zero warnings/errors; all 41 focused argument-group tests, scoped severity-info formatting verification, all 61 package baseline checks, and diff checks pass under the default guard limits.

Authoritative replacement gcloud generation is now running from this source at https://github.com/thomhurst/ModularPipelines/actions/runs/34802649779, with auto-merge and coverage-shrinkage approval disabled. This addresses the prerequisite to the current Codex finding 4001787137; the finding remains open until the generated output is incorporated and validated. #4877 must be refreshed before it is eligible for merge. No generated files were hand-edited.

@thomhurst
thomhurst force-pushed the issue-4799-gcloud-group-descriptions branch from b3c750f to 0f63058 Compare September 14, 2026 05:02
@thomhurst

Copy link
Copy Markdown
Owner Author

Manual review of the authoritative #4926 output found a remaining header defect: --logs-path and --process-count inherited download/upload enum descriptions because the flag regex rejected defaults such as <DownloadType.FILE: 'FILE'>.

Fixed in 0f63058. Default annotations are now treated as display text, preserving each header as a declaration. An unmodified SDK 550.0.0 Windows storage-diagnose fixture reproduces the same syntax visible in SDK 584.0.0 generation; its regression failed before the fix and now verifies restored strategy flags, string paths, integer counts, and exact descriptions. All 1,432 generator tests pass; Release build has zero warnings/errors. Scoped severity-info formatting verification and all 61 API baseline checks pass under unchanged resource guards. The four existing patches are unchanged after rebasing onto main c66bb4e.

Replacement authoritative generation is running from the new source at https://github.com/thomhurst/ModularPipelines/actions/runs/34808204420 with auto-merge and coverage-shrinkage approval disabled. Keeping the generated-output finding open until the replacement is reviewed and incorporated. #4926 must not merge its current output; generated options and baselines were not manually patched.

@thomhurst
thomhurst deployed to Pull Requests September 14, 2026 05:06 — with GitHub Actions Active
@github-actions

Copy link
Copy Markdown
Contributor

Review

Reviewed the current head (0f63058a) against the full diff (5 squashed-looking commits) and the prior review threads on this PR.

Prior blocking issue is resolved / no longer applicable. Earlier rounds (commits 923abaf, 7e58658) were blocked on an invalid with(StringComparer.Ordinal) collection-expression in GeneratorUtils.cs. That file is not part of the current diff at all — the file list for this head is just CliArgumentGroupParser.cs, GcloudCliScraper.cs, the two test files, and the two new fixtures. The PR author's later comments confirm the unrelated ConfigureAwait/branch-isolation changes were dropped after rebasing onto main, which already contains them. So that blocking finding doesn't apply to what's being reviewed here.

Core fix looks correct. Traced both logic changes by hand against the new authoritative fixtures and the existing test suite:

  • CliArgumentGroupParser.cs: widening the prelude-boundary check from < to <= (prelude indentation vs. the next declaration's indentation) is what lets a plain-text heading at the same indentation as its flags start a new group instead of being appended to the enclosing group's description. I walked the metastore-services-migrations-start.txt fixture through AddArgument/MoveToContainingGroup by hand: the Hive heading correctly becomes a sibling group under root, and the pop-then-push logic correctly separates it from the following Iceberg heading. I also checked every existing test in NestedArgumentGroupParsingTests.cs that has a prelude/declaration pair — in all of them the prelude's minimum indentation is already strictly less than the next declaration's indentation, so none of them exercise the new <= branch and none should regress.
  • GcloudCliScraper.cs: relaxing GcloudFlagPattern's trailing default= group from ("[^"]*"|'[^']*'|\S+) to [^\r\n]+ is necessary and correctly scoped — the old alternatives couldn't span an embedded space (e.g. default=<DownloadType.FILE: 'FILE'>), so those flag lines silently failed to match at all, which is exactly the mechanism that let the header bleed into the next recognized flag's documentation. The new pattern still requires a leading --flag/--[no-]flag token, so it doesn't broaden what counts as a flag line, only what trailing default annotation is tolerated.
  • The rest of the GcloudCliScraper.cs diff is a mechanical Regex.Match[GeneratedRegex] conversion for the fixed-pattern regexes in the same file (the one dynamic-pattern regex in ExtractFromSection is correctly left as-is, since [GeneratedRegex] requires a compile-time constant). No behavior change there.

Not verified by execution. I wasn't able to run dotnet build/dotnet test in this review sandbox (the build command required interactive approval that isn't available here), so this is a static trace, not a compiler/test-verified confirmation. Given the file-list scope (no non-generator files touched, no hand-edited generated options) and the PR's own cited CI/local runs (1,432 generator tests passing per the description), I'd treat that as sufficient corroboration, but flagging the limitation for transparency.

No actionable findings. The change stays within the stated scope (scraper/generator generic logic only, regression tests use unmodified real --help captures per repo convention), and I didn't find a case where the <= boundary widening changes behavior for any existing fixture.

@greptile-apps

greptile-apps Bot commented Sep 14, 2026

Copy link
Copy Markdown

Too many files changed for review (1664 files, 100 file limit).

@thomhurst
thomhurst deployed to Pull Requests September 14, 2026 08:28 — with GitHub Actions Active
@github-actions

Copy link
Copy Markdown
Contributor

Review

Reviewed the current head (cd0f2b1a) against the prior review threads on this PR. The CliArgumentGroupParser.cs/GcloudCliScraper.cs logic itself is unchanged since the last (CLEAR) round at 0f63058a; the only new commit is the bot-generated "Update gcloud CLI options" regeneration, which is why the diff now exceeds GitHub's 300-file API limit. I compared the base checkout against pr-head/ directly to get past that limit and focused on the hand-authored parser/scraper logic rather than the regenerated option files.

Actionable: the new same-indentation heuristic can evict an already-classified flag out of its mutually-exclusive group.

CliArgumentGroupParser.cs:57-58 now treats a prelude as starting a new group whenever preludeIndentation <= declaration.Argument.Indentation, with no keyword match required:

var preludeStartsGroup = StartsArgumentGroup(preludeLines, prelude)
    || preludeIndentation <= declaration.Argument.Indentation;

Tracing AddArgument (CliArgumentGroupParser.cs:135-165) for a group that's already been classified by a keyword (e.g. an "At most one of these can be specified:" heading that pushed an AtMostOne child group for --token), a plain narrative aside at the same indentation as the next sibling flag — e.g. a "Note: ..." or clarifying sentence between --token and --profile inside that same logical group — now satisfies preludeStartsGroup purely on indentation. Since argument.Indentation isn't > the current frame's indentation, the else if (preludeStartsGroup) branch pops the AtMostOne frame off the stack and creates a new sibling group under root for --profile, seeded only with the aside text as its description. --profile loses the AtMostOne Kind classification and its membership in the mutually-exclusive set entirely — a worse outcome than the pre-PR behavior, which would have appended that same aside to the existing group's description via AppendDescription (line 161) and left --profile correctly nested.

This doesn't reproduce against any current fixture — the two new tests (GcloudGroupDescriptionTests.cs, NestedArgumentGroupParsingTests.cs) and the authoritative metastore-services-migrations-start.txt fixture only exercise a heading immediately preceding the first flag of a new sibling group, never a narrative aside sandwiched between two flags that are already inside an established, keyword-classified group. But CliArgumentGroupParser/CliScraperBase is shared infrastructure used by every CLI scraper (aws, az, terraform, gcloud, npm, ...), so this is a latent regression risk beyond gcloud, not a one-off fixture gap.

Why this is an architectural gap, not just a missing test case: the indentation-equality heuristic can't distinguish "this prose introduces a new named subsection" (should evict/create a sibling) from "this prose is a mid-group aside" (should just extend the current group's description) — both look identical from indentation alone. A sturdier signal would be to only let the indentation-based path evict the current frame when the current frame doesn't already carry a non-None Kind classification (i.e. don't kick a flag out of an already-established AtMostOne/AtLeastOne/Alternative/Resource group based on indentation alone — require an explicit keyword match to override a classified group, and reserve the indentation heuristic for frames that haven't been classified yet, which is exactly the Hive/Iceberg case this PR targets). That keeps the real bug fixed while closing off the eviction path for already-classified groups.

Everything else holds up:

  • The <= widening's effect on the real Hive/Iceberg and enum-default-with-embedded-space fixtures is correct — I re-traced both through AddArgument/MoveToContainingGroup by hand and they resolve as intended, matching the prior round's analysis.
  • Regex.Match(...)[GeneratedRegex] conversions in GcloudCliScraper.cs are faithful 1:1 pattern extractions.
  • The Logger.IsEnabled guard avoids object[] boxing on scraper construction — benign.
  • No hand-edited generated option files; changes stay confined to scraper/generator logic per repo convention.
  • The Groups.Select(...).ToArray()[.. Groups.Select(...)] collection-expression change is a safe mechanical simplification.

@thomhurst

Copy link
Copy Markdown
Owner Author

Fixed the narrative-aside finding in comment 5661323520 with 160e06d. Four regressions reproduce same-indentation prose splitting AtMostOne, AtLeastOne, Alternative, and Resource groups. The parser now checks the containing frame after indentation unwinding and permits an indentation-only sibling only for an unclassified frame. Explicit headings still start siblings.

All 1,437 generator tests pass, including all 47 group tests and the existing authoritative Hive/Iceberg and enum-default fixtures. Release build has zero warnings/errors; scoped info verification and diff checks pass. Fresh full Gcloud generation: https://github.com/thomhurst/ModularPipelines/actions/runs/34824921392. The prior #4926 output is incorporated, but this new source requires final provenance before merge.

@thomhurst
thomhurst deployed to Pull Requests September 14, 2026 08:55 — with GitHub Actions Active
@thomhurst
thomhurst merged commit 4f9c42c into main Sep 14, 2026
21 checks passed
@thomhurst
thomhurst deleted the issue-4799-gcloud-group-descriptions branch September 14, 2026 12:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant