Skip to content

feat(derive): support clap implicit groups - #1137

Merged
jdx merged 1 commit into
agent/clap-command-metadatafrom
agent/clap-implicit-groups
Aug 21, 2026
Merged

feat(derive): support clap implicit groups#1137
jdx merged 1 commit into
agent/clap-command-metadatafrom
agent/clap-implicit-groups

Conversation

@jdx

@jdx jdx commented Aug 20, 2026

Copy link
Copy Markdown
Owner

Summary

  • accept clap's struct-level #[group(...)] helper attribute
  • place direct Args fields into the derived implicit group
  • preserve clap's default multiple(true) and explicit required/multiple/skip settings

Verification

  • cargo test -p usage-rs --test facade clap_implicit_groups_apply_to_the_args_struct_fields
  • cargo clippy -p usage-derive --all-targets --all-features -- -D warnings

This pull request was generated by Codex.


Note

Medium Risk
Touches derive parsing and how required flags/groups are encoded in generated parsers and specs. Wrong mapping would change CLI validation and portable KDL, but behavior is covered by facade tests.

Overview
Adds clap-compatible struct-level #[group(...)] on Cli/Args derives so an Args struct’s direct flags and positionals form an implicit group (clap defaults: multiple(true), optional required/id/skip).

Membership is joined from both field group = "..." and implicit group member lists. One-member required implicit groups do not emit a spec group; they lower onto the field as ordinary requiredness (metadata, help, and runtime MissingRequired). Multi-member implicit groups that only restated clap’s default multiple without required are omitted from emitted group metadata.

Reviewed by Cursor Bugbot for commit bc00e65. Bugbot is set up for automated code reviews on this repo. Configure here.

@coderabbitai

coderabbitai Bot commented Aug 20, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Central YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 0db5db98-51d1-459c-a05b-649b8cc8a984

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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

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

@jdx
jdx force-pushed the agent/clap-implicit-groups branch 2 times, most recently from 1065776 to b8992fb Compare August 20, 2026 15:46
@github-actions

github-actions Bot commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Instruction counts

benchmark trend instructions Δ wall (min) Δ
markdown ▄▁█ 199,368,396 → 219,462,294 +10.08% ⚠️ 18.76 → 22.52ms +20.03%
startup ▁██ 1,221,718 → 1,221,447 -0.02% 1.30 → 1.58ms +21.90%

1 benchmark(s) above the 1% gate: markdown +10.08%

Only instruction counts gate. Wall clock is shown for context — on identical hardware it moves 4-20% run to run.

Measured by tak — instruction-counted CLI benchmarks, stored in this repository's git notes.

Shadow comparison

Parsing mise use -g node@20 against a shadow of mise's committed spec.
Reported, not gated: the shadow grows as the derive learns to express more, so
what to watch is the ratio rather than either column.

framework instructions, cold parse vs usage
usage 4355
argh 6292 1.4x
clap 5893640 1353x
bpaf 21917948 5032x
                                              min       p01       p10    median
usage-rs: argv -> struct                      194       198       201       207  ns
argh: argv -> struct                          283       288       294       306  ns
clap: build tree + parse -> struct         486625    487560    491640    504963  ns
bpaf: build parser + parse -> struct      1649776   1649776   1662952   1681108  ns

usage: argv -> struct                             199 ns      0.20 µs
clap: build tree + parse -> struct             504869 ns    504.87 µs
clap: parse -> struct, tree reused              22969 ns     22.97 µs
clap: build tree only                          309420 ns    309.42 µs

203b9d56bbc3 vs e5c8eb0982a6 · measured on the runner, not pushed to the history.

@jdx
jdx force-pushed the agent/clap-implicit-groups branch from b8992fb to 41d459e Compare August 20, 2026 16:03
Comment thread derive/src/model.rs
Comment thread derive/src/model.rs
@jdx
jdx force-pushed the agent/clap-implicit-groups branch from 41d459e to 76343ae Compare August 20, 2026 16:16

jdx commented Aug 20, 2026

Copy link
Copy Markdown
Owner Author

Addressed both new implicit-group findings in this PR:

  • a direct field now remains a member of clap’s implicit Args group even when it also names an explicit group;
  • repeated #[group(...)] attributes apply cumulatively, so splitting id/required and multiple/skip does not reset earlier settings.

The facade regression covers split attributes, dual membership, requiredness, and exclusivity.

This comment was generated by Codex.

@jdx
jdx force-pushed the agent/clap-implicit-groups branch from 76343ae to b53525b Compare August 20, 2026 16:27
Comment thread derive/src/model.rs
@jdx
jdx force-pushed the agent/clap-implicit-groups branch 2 times, most recently from c44c296 to ed320f1 Compare August 20, 2026 16:35
Comment thread derive/src/codegen.rs
@jdx
jdx force-pushed the agent/clap-implicit-groups branch from ed320f1 to 8b899b8 Compare August 20, 2026 17:11
Comment thread derive/src/codegen.rs
@jdx
jdx force-pushed the agent/clap-implicit-groups branch from 8b899b8 to 9268df9 Compare August 20, 2026 17:24
@jdx
jdx force-pushed the agent/clap-implicit-groups branch from 9268df9 to 203b9d5 Compare August 21, 2026 01:50
@jdx
jdx force-pushed the agent/clap-implicit-groups branch 2 times, most recently from 2d6d79c to 49a59e0 Compare August 21, 2026 03:20
@jdx
jdx force-pushed the agent/clap-implicit-groups branch 2 times, most recently from aaaba60 to cb87cb8 Compare August 21, 2026 05:19
@jdx
jdx force-pushed the agent/clap-implicit-groups branch from cb87cb8 to 310e63f Compare August 21, 2026 05:36
@jdx
jdx force-pushed the agent/clap-implicit-groups branch 2 times, most recently from 514dcb5 to 0d5d290 Compare August 21, 2026 06:08
@jdx
jdx force-pushed the agent/clap-implicit-groups branch from 0d5d290 to cd05d2c Compare August 21, 2026 06:11
@jdx
jdx force-pushed the agent/clap-implicit-groups branch 2 times, most recently from d7d71f0 to a8c98b9 Compare August 21, 2026 06:35
@jdx
jdx force-pushed the agent/clap-implicit-groups branch from a8c98b9 to 58f1c86 Compare August 21, 2026 06:46
@jdx
jdx force-pushed the agent/clap-implicit-groups branch from 58f1c86 to 0eef7e0 Compare August 21, 2026 06:56
@jdx
jdx force-pushed the agent/clap-implicit-groups branch from 0eef7e0 to 0f88e21 Compare August 21, 2026 07:10
@jdx
jdx force-pushed the agent/clap-implicit-groups branch 2 times, most recently from 8fa7de7 to b0516d3 Compare August 21, 2026 07:30
@jdx
jdx force-pushed the agent/clap-implicit-groups branch from b0516d3 to 2fdaff5 Compare August 21, 2026 07:49
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