Skip to content

Support help as a command or action, like --help - #942

Open
lyelgate wants to merge 1 commit into
linode:devfrom
lyelgate:feat/help-subcommand
Open

lyelgate wants to merge 1 commit into
linode:devfrom
lyelgate:feat/help-subcommand

Conversation

@lyelgate

@lyelgate lyelgate commented Nov 1, 2026

Copy link
Copy Markdown

📝 Description

What does this PR do and why is this change necessary?

Fixes #868.

help now works like the --help flag when given as the command or the action:

Command Before After
linode-cli help Unrecognized command help (exit 1) same as linode-cli --help
linode-cli help linodes Unrecognized command help (exit 1) same as linode-cli linodes --help
linode-cli linodes help Action not found for command linodes: help (exit 2) same as linode-cli linodes --help
linode-cli help linodes create Unrecognized command help (exit 1) same as linode-cli linodes create --help
linode-cli obj help (handled by the plugin) same as linode-cli obj --help

This is a new take on #878, which was closed with review feedback outstanding. The feedback is addressed:

  • sys.argv is changed in place, not reassigned. linodecli/__init__.py holds from sys import argv and builds plugin arguments from it, so reassigning would desync them. help_subcommand_to_flag deletes the help token and appends --help on the same list, then main() re-parses with the same parser.
  • Only the command and action positions are rewritten. They come from the parsed arguments, so global options before the command (linode-cli --json linodes help) still work, and help as a value is untouched: linode-cli obj mb help still creates a bucket named help, and linode-cli linodes view help still passes help as the ID.
  • The tests are plain unit tests with no subprocess and no hard-coded paths, so they run on Windows too. They cover both the help <command> and <command> help forms.

✔️ How to Test

What are the steps to reproduce the issue or verify the changes?

linode-cli help linodes
linode-cli linodes help
linode-cli help linodes create
linode-cli obj help

With a baked spec, I compared the output of each of these and of linode-cli help with its --help equivalent. They are identical, with exit code 0.

How do I run the relevant unit/integration tests?

LINODE_CLI_TEST_MODE=1 pytest tests/unit/test_arg_helpers.py -k help_subcommand

The tests run each case through the real register_args parser and check the rewritten arguments: six rewritten forms (including a global option before the command, a plugin, and that the list is changed in place) and four that must be left alone. black, isort, autoflake and pylint pass, and so does make test-unit (250 tests) with a baked spec.

`linode-cli help linodes` and `linode-cli linodes help` failed with
"Unrecognized command help" and "Action not found for command linodes:
help". Treat `help` given as the command or the action like the --help
flag, so both show the same help as `linode-cli linodes --help`;
`linode-cli help` shows the default help and `linode-cli help linodes
create` the help for an action.

Only the command and action positions are rewritten, since `help`
elsewhere can be a value, such as a bucket name in
`linode-cli obj mb help`. argv is changed in place, so plugins, which
read it directly, see the --help flag too.

Fixes linode#868
@lyelgate
lyelgate requested review from a team as code owners November 1, 2026 11:35
@lyelgate
lyelgate requested review from jriddle-linode and psnoch-akamai and removed request for a team November 1, 2026 11:35

This branch has not been deployed

No deployments
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.

[Feature]: support "help" as a subcommand synonymous with "--help"

1 participant