Skip to content

fix(generator): preserve documented gcloud branch optionality - #5342

Merged
thomhurst merged 3 commits into
mainfrom
maintenance/gcloud-documented-branch-optionality-20260922
Sep 22, 2026
Merged

thomhurst merged 3 commits into
mainfrom
maintenance/gcloud-documented-branch-optionality-20260922

Conversation

@thomhurst

@thomhurst thomhurst commented Sep 22, 2026

Copy link
Copy Markdown
Owner

Fresh Google snapshot #5341 rejects valid Cluster Director granular updates because SYNOPSIS adjacency was interpreted as a requirement for every branch member. It also incorrectly requires every OAuth credential/PKCE flag despite SDK 585 declaring those members optional. Conversely, enabling GKE autoprovisioning must retain its explicitly documented resource-limit dependency.

Preserve per-member and nested-choice requiredness from FLAGS while using SYNOPSIS for branch boundaries. Parse explicit named requirements such as "Required to be set when --enable-autoprovisioning is used" into conditional constraints, retaining documented config-file alternatives. The generator activates those constraints only when their trigger is present; stable CLI member identities preserve activation through property renaming. Conditional constraints cannot replace unconditional usage requirements.

Captured SDK 585 generated-validator regressions cover Cluster Director, Composer, GKE, Storage, Cloud Build, and optional OAuth members. The runtime helper compiles generated enums alongside options. Generic conditional tests cover absent/false triggers and renamed properties.

Related: #5339. Defective generated PR #5341 is closed, and all its pending CI was cancelled and verified clear. Another latest-main snapshot is required after this source fix merges.

Validation: Cluster Director, corrected OAuth, and enabling-only GKE cases fail before their fixes. All 38 focused checks pass: 18 Google generated-validator tests, eight conditional-activation cases, and 12 synopsis/upload/Dataplex cases. Formatting passes. Full CI passes all 3,379 generator tests on 720321d. CodeQL, CodeFactor, Claude, CodeRabbit, and Codex all pass on the current head; no outstanding review findings remain. No local resource limit was raised.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 22, 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-22T03:14:05.488999Z 720321d Manual request
ℹ️ 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.

@coderabbitai

coderabbitai Bot commented Sep 22, 2026

Copy link
Copy Markdown

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

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: b5036cb8-76c5-4cb3-a5e7-89d28cacae71

📥 Commits

Reviewing files that changed from the base of the PR and between e8482e5 and 720321d.

📒 Files selected for processing (9)
  • tools/ModularPipelines.OptionsGenerator/src/ModularPipelines.OptionsGenerator.Tests/Generators/ConditionalRequiredGroupValidationTests.cs
  • tools/ModularPipelines.OptionsGenerator/src/ModularPipelines.OptionsGenerator.Tests/Generators/GcloudNestedSynopsisValidationTests.cs
  • tools/ModularPipelines.OptionsGenerator/src/ModularPipelines.OptionsGenerator.Tests/Generators/GcloudPeerResourceValidationTests.cs
  • tools/ModularPipelines.OptionsGenerator/src/ModularPipelines.OptionsGenerator/Generators/InheritedPropertyCollisionResolver.cs
  • tools/ModularPipelines.OptionsGenerator/src/ModularPipelines.OptionsGenerator/Generators/OptionsClassGenerator.cs
  • tools/ModularPipelines.OptionsGenerator/src/ModularPipelines.OptionsGenerator/Models/CliRequiredAlternativeGroup.cs
  • tools/ModularPipelines.OptionsGenerator/src/ModularPipelines.OptionsGenerator/Scrapers/Cli/CliScraperBase.cs
  • tools/ModularPipelines.OptionsGenerator/src/ModularPipelines.OptionsGenerator/Scrapers/Cli/GcloudCliScraper.ConditionalRequirements.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 scraper now models conditional requiredness and preserves optional documented choices. New gcloud 585.0.0 fixtures cover three update commands. Tests validate conditional groups, optional alternatives, OAuth branches, and generated options.

Changes

Gcloud requiredness preservation

Layer / File(s) Summary
Conditional requiredness parsing and generation
tools/ModularPipelines.OptionsGenerator/src/ModularPipelines.OptionsGenerator/Models/CliRequiredAlternativeGroup.cs, tools/ModularPipelines.OptionsGenerator/src/ModularPipelines.OptionsGenerator/Scrapers/Cli/*, tools/ModularPipelines.OptionsGenerator/src/ModularPipelines.OptionsGenerator/Generators/*
Adds RequiredWhen metadata. The scraper extracts named conditional requirements. The generator activates these groups when the trigger property is present.
Capture gcloud update help
tools/ModularPipelines.OptionsGenerator/src/ModularPipelines.OptionsGenerator.Tests/Fixtures/Gcloud/585.0.0/*update.txt
Adds gcloud 585.0.0 help fixtures for cluster-director, Composer, and container cluster update commands.
Validate generated requiredness
tools/ModularPipelines.OptionsGenerator/src/ModularPipelines.OptionsGenerator.Tests/Generators/*
Adds tests for conditional activation, optional resource settings, OAuth branch members, nested groups, and generated enum compilation.

Priority: ⬇️ Low

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

Change: Bug fix

Possibly related PRs

Merge Risk: ⚪ Minimal · up to 72032

The generator now applies conditional requirements only when their documented triggers are present, while preserving optional choices; focused validation and formatting checks are reported passing.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 20 functions across 9 files. 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: preserving documented optionality for gcloud branches in the generator.
  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

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 checks each flag in line
And finds the conditional sign
Optional branches stay light
Required groups wake at the right
Three new help files join the tune
Tests hop beneath the validation moon

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

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Claude Review

PR fixes GcloudCliScraper.PreserveDocumentedChoices so per-member and group-level requiredness inside a documented FLAGS branch is preserved from FLAGS "Required" markers instead of being inferred purely from SYNOPSIS adjacency. Previously, adjacent flags in a SYNOPSIS branch were all marked required together, incorrectly forcing every Cluster Director granular-update flag and every OAuth credential/PKCE flag to be mandatory. The fix now only keeps a member required if it was already required and a documented candidate confirms it as required, and only overrides the group's own IsRequired when the group is itself a documented choice. Test infrastructure was extended to compile real generated enums alongside options so the larger captured commands (with enum-typed flags) can be compiled and validated without changing their types.

Review evidence

tools/ModularPipelines.OptionsGenerator/src/ModularPipelines.OptionsGenerator/Scrapers/Cli/GcloudCliScraper.cs: Verified PreserveDocumentedChoices now derives Members[].IsRequired and the group's own IsRequired (when IsChoice) from the flattened 'documented' FLAGS-section tree rather than carrying over blanket SYNOPSIS-adjacency requiredness; the change is a minimal, additive 9-line diff inside an existing 'with' expression and does not touch RestoreFlattenedDocumentedChoices or ConvertSynopsisConstraint.

tools/ModularPipelines.OptionsGenerator/src/ModularPipelines.OptionsGenerator.Tests/Generators/GcloudNestedSynopsisValidationTests.cs: New Cluster Director, Composer, and renamed OAuth tests exercise the fixed branch: confirmed against the new gcloud-cluster-director-clusters-update.txt and gcloud-agent-identity-auth-providers-create.txt fixtures that none of the individually-optional flags (Description, RemoveLabels, OAuth sub-fields) carry a documented 'Required' marker, while Config/UpdateMask correctly remain a required companion pair per the FLAGS section.

tools/ModularPipelines.OptionsGenerator/src/ModularPipelines.OptionsGenerator.Tests/Generators/GcloudPeerResourceValidationTests.cs: ValidateCapturedGroup now compiles EnumGenerator output alongside the generated options class; verified EnumGenerator.cs and CliToolDefinition (ToolName/NamespacePrefix/TargetNamespace/OutputDirectory/Commands) exist in src/ModularPipelines.OptionsGenerator/Generators and Models, so the referenced API is real and the helper change is necessary for compiling captured commands containing enum-typed flags (e.g. Composer's EnvironmentSize).

tools/ModularPipelines.OptionsGenerator/src/ModularPipelines.OptionsGenerator.Tests/Fixtures/Gcloud/585.0.0/gcloud-container-clusters-update.txt: Spot-checked the nested autoprovisioning 'Or at least one'/'Exactly one' groups to confirm AutoprovisioningConfigFile and AutoprovisioningMinCpuPlatform sit in mutually exclusive nested branches, matching the new test's expectation that combining them is invalid.

No actionable findings.

Optional follow-up notes

The OAuth test (Gcloud_Agent_Identity_Oauth_Preserves_Optional_Members_Within_Exclusive_Branches) now treats a single member of the three-legged or two-legged branch as independently valid (e.g. specifying only --three-legged-oauth-enable-pkce with none of the client id/secret/token-url flags passes validation). This matches the SDK 585 FLAGS section, which marks none of these sub-fields as individually 'Required', so the generator is correctly avoiding invented constraints; however consumers relying on generated validation to catch an incomplete OAuth flow at construction time will no longer get that safety net for this command. Worth flagging to gcloud command consumers/docs if runtime failures from incomplete OAuth flows become a support burden, but not a defect in this PR's stated scope.

The member-requiredness lookup in PreserveDocumentedChoices (GcloudCliScraper.cs lines 426-430) matches documented candidates purely by PropertyName across the whole flattened 'documented' tree rather than scoping to the corresponding branch. This is safe today because gcloud property names are unique per command, but if a future command ever reused the same generated PropertyName as required in one documented branch and optional in a sibling branch, this global match could misclassify it. Not actionable now since no current fixture exercises that case, but worth keeping in mind if a future generator regression report references this method.

@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: e8482e5a89

ℹ️ 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".

@thomhurst

Copy link
Copy Markdown
Owner Author

CodeFactor complexity finding is addressed in 720321d, confirmed at the remote head. Conditional activation now has a separate helper, preserving generated behavior. All 26 affected runtime/activation tests pass after the refactor; the 12 parser regressions and formatting also pass. Full CI and reviews are running again.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Claude Review

This PR refines GcloudCliScraper.PreserveDocumentedChoices to derive per-member and per-group requiredness from documented FLAGS 'Required' markers instead of blanket SYNOPSIS-adjacency, fixing false-positive validation failures for Cluster Director granular updates and OAuth optional sub-fields. It also adds a new RequiredWhen conditional-activation mechanism (CliRequiredAlternativeGroup.RequiredWhen, GcloudCliScraper.ApplyNamedConditionalRequirements, OptionsClassGenerator.ResolveConditionalActivation) so explicit prose like 'Required to be set when --enable-autoprovisioning is used' still enforces max-cpu/max-memory only when the trigger flag is present, addressing a Codex P2 finding from this same PR's review thread. I traced the logic against the new 585.0.0 fixtures (Cluster Director, Composer, GKE autoprovisioning) and the updated/added tests, and it behaves as documented.

Review evidence

tools/ModularPipelines.OptionsGenerator/src/ModularPipelines.OptionsGenerator/Scrapers/Cli/GcloudCliScraper.cs: Verified PreserveDocumentedChoices now derives per-member IsRequired and the group's own IsRequired (when IsChoice) from documented FLAGS 'Required' markers rather than SYNOPSIS adjacency, matching the Cluster Director and Composer fixtures where granular/description/label flags are not individually 'Required' but Config/UpdateMask remain a required pair.

tools/ModularPipelines.OptionsGenerator/src/ModularPipelines.OptionsGenerator/Scrapers/Cli/GcloudCliScraper.ConditionalRequirements.cs: New partial class parses 'Required to be set when --X is used' prose via regex, locates the matching documented mutually-exclusive alternative (e.g. config-file vs. resource-limit bundle), and adds a RequiredWhen-gated duplicate constraint; traced against the GKE autoprovisioning max-cpu/max-memory case and confirmed it activates only when --enable-autoprovisioning is set.

tools/ModularPipelines.OptionsGenerator/src/ModularPipelines.OptionsGenerator/Generators/OptionsClassGenerator.cs: ResolveConditionalActivation forces required=true and combines the trigger's presence expression into the activation guard only when group.RequiredWhen is set, verified to run before both group-level and per-member validation emission for every recursion level.

tools/ModularPipelines.OptionsGenerator/src/ModularPipelines.OptionsGenerator/Models/CliRequiredAlternativeGroup.cs: Confirmed the new optional RequiredWhen field defaults to null, preserving backward compatibility for all existing unconditional alternative groups across other CLI scrapers.

tools/ModularPipelines.OptionsGenerator/src/ModularPipelines.OptionsGenerator/Scrapers/Cli/CliScraperBase.cs: Verified the inferred-group dedup check now excludes conditional (RequiredWhen != null) groups from satisfying an unconditional synopsis requirement, so a conditional constraint no longer silently suppresses an otherwise-needed unconditional inferred group.

tools/ModularPipelines.OptionsGenerator/src/ModularPipelines.OptionsGenerator.Tests/Generators/GcloudNestedSynopsisValidationTests.cs: New Cluster Director, Composer, and GKE autoprovisioning test cases cross-checked line-by-line against the captured FLAGS wording in the new fixtures confirm the valid/invalid property combinations match documented requiredness and mutual exclusivity.

tools/ModularPipelines.OptionsGenerator/src/ModularPipelines.OptionsGenerator.Tests/Generators/GcloudPeerResourceValidationTests.cs: ValidateCapturedGroups was extended to compile EnumGenerator output alongside generated options and to include RequiredWhen trigger properties in the compiled option set, verified necessary for the enum-typed Composer/GKE fixtures used by the new tests.

No actionable findings.

Optional follow-up notes

PreserveDocumentedChoices still matches documented candidates by PropertyName across the whole flattened tree rather than scoping to the corresponding branch (GcloudCliScraper.cs). This was already flagged in a prior review as safe today (gcloud property names are unique per command) but worth remembering if a future command reuses the same property name as required in one branch and optional in a sibling branch.

The OAuth create command (gcloud-agent-identity-auth-providers-create.txt) now allows selecting a single sub-field of the three-legged/two-legged branch without requiring the rest, matching SDK 585 FLAGS documentation but removing the previous safety net that caught incomplete OAuth configurations at construction time. Already surfaced as a non-blocking follow-up in the prior review round.

InheritedPropertyCollisionResolver.cs now renames group.RequiredWhen via the same ResolveAlternativeMemberName helper used for Members, but no test in this PR (or ConditionalRequiredGroupValidationTests.cs) exercises an actual property rename/collision scenario for a RequiredWhen trigger — the existing conditional test only passes matching literal PropertyName strings ('Enabled'/'Clone') without routing through the collision resolver. Since the PR description claims 'stable CLI member identities preserve activation through property renaming,' a dedicated test resolving a real collision (e.g., a trigger option whose SwitchName maps to a renamed property) would substantiate that claim, even though the shared helper is already covered for regular Members.

ApplyNamedConditionalRequirements (GcloudCliScraper.ConditionalRequirements.cs) handles a named 'Required to be set when X is used' dependency by finding the matching documented exclusive alternative subtree and then appending a brand-new, fully duplicated copy of that subtree as a separate top-level constraint with RequiredWhen set, rather than mutating the existing node in place at its original tree position. This works correctly for the covered fixtures, but keeping two independent copies of the same branch shape (one unconditional/inactive, one conditional) means future changes to that branch's structure must be kept in sync manually in two places. Attaching RequiredWhen directly to the located node within the existing tree (replacing it in place) would keep a single source of truth for the branch and reduce the risk of the two copies drifting apart.

@thomhurst

Copy link
Copy Markdown
Owner Author

Thanks for the review. Two optional notes are already covered by the implementation:

  • The Clone cases in ConditionalRequiredGroupValidationTests call the real OptionsClassGenerator.Generate, which invokes InheritedPropertyCollisionResolver.Resolve before emitting code. These cases therefore exercise an actual reserved-name rename and verify that the RequiredWhen trigger still activates through its stable OptionSwitch identity.
  • The conditional constraint is derived from the parsed alternative on every generation. It is not a second manually maintained definition. Keeping the unconditional constraint also preserves mutual exclusivity when the trigger is absent; replacing it with a conditional constraint would lose that validation.

The SDK fixture remains authoritative for OAuth CLI optionality. Server-side configuration requirements do not justify introducing unsupported CLI requirements.

All 3,379 generator tests passed at 720321deb6c03958700ce4669547cd8c1ded0a37.

@thomhurst

Copy link
Copy Markdown
Owner Author

@codex review Please review the current head 720321d. The previous review has a positive reaction, but its summary still reports Running since 02:44 UTC. All 3,379 generator tests and CodeQL now pass; the earlier conditional-requirement finding is fixed and resolved.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. What shall we delve into next?

Reviewed commit: 720321deb6

ℹ️ 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".

@thomhurst
thomhurst merged commit c2ccb29 into main Sep 22, 2026
16 checks passed
@thomhurst
thomhurst deleted the maintenance/gcloud-documented-branch-optionality-20260922 branch September 22, 2026 03:14
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