Skip to content

cli: render command groups, inherited flags, examples and learn-more in --help#27124

Open
davlgd wants to merge 2 commits into
vlang:masterfrom
davlgd:davlgd-cli-help-sections
Open

cli: render command groups, inherited flags, examples and learn-more in --help#27124
davlgd wants to merge 2 commits into
vlang:masterfrom
davlgd:davlgd-cli-help-sections

Conversation

@davlgd
Copy link
Copy Markdown
Contributor

@davlgd davlgd commented May 10, 2026

This PR teaches vlib/cli's --help rendering about four extra sections. Three are unlocked by new optional fields on Command (none of which render anything unless populated):

  • group string on a sub-command — its parent's listing splits into one section per group, named after the group string verbatim followed by :. Sub-commands without a group keep falling back to the default Commands: block. Helpful for CLI with lots of commands.
  • examples []string — rendered under a new Examples: section, one entry per indented line.
  • learn_more string — rendered under a new Learn more: section, with newlines splitting the block into separate lines.

The fourth uses the existing Flag.global field to split inherited flags into their own section: any ancestor declared with Flag.global = true now move out of the local Flags: block into a separate Inherited flags: section, so a sub-command's own surface stays readable.

The motivation is to bring vlib/cli closer to widely-used CLI conventions (named sections, grouped sub-commands, examples, inherited flags), as recommended by the Command Line Interface Guidelines for example, while keeping V's existing Usage: / Flags: / Commands: visual style so adopting the new fields never feels like a different tool.

Rendering

Running examples/cli_groups.v with --help produces:

Usage: tasky [flags] [commands]

A tiny issue tracker CLI

Flags:
  -c  --config        Path to a tasky config file
  -h  --help          Prints help information.
  -v  --version       Prints version information.
      --man           Prints the auto-generated manpage.

Core commands:
  issue               Work with issues

Additional commands:
  config              Read or write tasky settings

Commands:
  help                Prints help information.
  version             Prints version information.
  man                 Prints the auto-generated manpage.

Examples:
  $ tasky issue list
  $ tasky issue create --title "Fix CI"
  $ tasky config get editor

Learn more:
  Use `tasky <command> --help` for details about a command.
  Documentation lives at https://example.test/tasky

Drilling into a sub-command surfaces the new Inherited flags: block:

$ tasky issue create --help
Usage: tasky issue create [flags]

Create a new issue

Flags:
  -t  --title         Title of the issue to create (required)
  -h  --help          Prints help information.
      --man           Prints the auto-generated manpage.

Inherited flags:
  -c  --config        Path to a tasky config file

A Command with none of the new fields populated and no inherited globals renders exactly like before: Usage: line, optional description, Flags:, Commands:. No new sections appear unless they have content.

How to try it

v -o tasky examples/cli_groups.v
./tasky --help
./tasky issue --help
./tasky issue create --help

The example exercises every new code path: groups (Core commands / Additional commands), an inherited global flag (-c, --config), an examples block and a multi-line learn_more block.

Tests

I've added four cases to vlib/cli/help_test.v:

  • test_help_message_groups_commands_by_group_field
  • test_help_message_renders_group_title_verbatim (UTF-8 safety: a group string starting with a multi-byte character renders without mojibake)
  • test_help_message_separates_inherited_flags_from_locals
  • test_help_message_renders_examples_and_learn_more
  • test_help_message_omits_empty_optional_sections

The two pre-existing assertions in test_help_message still pass unchanged, which is the strongest evidence that apps without the new fields see identical output.

Run with:

v -enable-globals test vlib/cli/

@medvednikov
Copy link
Copy Markdown
Member

Btw to enforce our "one way" policy I'll be keeping only flag in vlib.

cli will be moved to v install cli

@davlgd
Copy link
Copy Markdown
Contributor Author

davlgd commented May 10, 2026

Got it — happy to help with that move. Two questions:

  1. Should this PR (and cli: drop trailing periods and use 'Print' in default help/version/man descriptions #27123) land before the extraction, or do you prefer it goes into the new cli repo once it exists?
  2. Is there work I can pick up to help with the extraction itself?

@medvednikov
Copy link
Copy Markdown
Member

I'll merge it before the extraction. I'll do the extraction myself.

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.

2 participants