Skip to content

Print the help when --help or -h is unexpectedly encountered. #264

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from

Conversation

iwanders
Copy link

Most binaries used on Linux support the '--help' argument, this is a convention specified by the GNU project, as well as in the clig.

Currently, adding --help after a failing command gives an error, following by an note at the end on how to get the help. Actually getting the help usually involves pressing the up arrow, removing the erroneous --help at the end, moving the cursor to after picotool to insert help and then succesfully printing out the help.

This commit adds a new error type to the parser to distinguish between parse errors, and errors that can be identified as an attempt to obtain the help. This help error is raised only if an unexpected argument called --help is encountered, or an unexpected option -h.

In the main.cpp this specific error is now caught and handled on appropriately, still relying on the outer catch problematic parse errors, like using command names that don't exist.


Above the line is the commit message, I considered an example too long to be included in it, but before this commit the behaviour is as follows:

$ picotool partition info --help

ERROR: unexpected option: --help

SYNOPSIS:
    picotool partition info [-m <family_id>] [device-selection]

Use "picotool help partition info" for more info

With this commit, it instead does:

$ ./picotool partition info --help
ERROR: unexpected option: --help, this looks like you want the help:
INFO:
    Print the device's partition table.

SYNOPSIS:
    picotool partition info [-m <family_id>] [device-selection]

OPTIONS:
        -m <family_id>
            family ID (will show target partition for said family)
        ... more options.

Behaviour when subcommands don't exist is unmodified:

$ ./picotool this_doesnt_exist --help

ERROR: Unknown command: this_doesnt_exist

COMMANDS:
    info        Display information from the target device(s) or file.

Neither is behaviour when a secondary subcommand is not specified, so in case of picotool partition --help, the behaviour is unmodified as that situation already prints the available subcommands. It's really only handling --help and -h at the end of the commandline, which is muscle memory for many people that live in their terminals.

I at first tried to modify the signature of match to use an outparam, but that didn't work as any throws would still end up being handled by the outer throw. I didn't want to return a boolean return to indicate the help is desired, so instead I decided to subclass from the parse_error and make a more specific flavour of that.

I've only tested this on Debian GNU/Linux 12, I hope it works with MSVC, I did not find a CONTRIBUTING.md file or .clang-format file, so not sure if there's any tests I should/can run.

@iwanders iwanders force-pushed the add-handling-for--help branch 2 times, most recently from 1bbe801 to c58b619 Compare July 23, 2025 00:19
@iwanders
Copy link
Author

While using the new functionality I discovered two deficiencies my initial implementation, hence the force pushes. It's now greedily searching over the remaining arguments for -h or --help, instead of only checking the first argument that remains. I ran into this through:

$picotool partition create partitions.json  --verbose  /tmp/foo.uf2
# Cool, there's an uf2 file at /tmp/foo.uf2
$picotool --help
...
COMMANDS:
    info        Display information from the target device(s) or file. 
# Nice, lets call info on that file we just created.
$picotool uf2 info /tmp/foo.uf2
ERROR: unexpected argument: /tmp/foo.uf2
$ picotool uf2 info /tmp/foo.uf2  --help
ERROR: unexpected argument: /tmp/foo.uf2

Because the parse error happens on the first unmatched argument.

With the latest version, we get (for the last command):

picotool uf2 info /tmp/foo.uf2 --help
ERROR: unexpected argument: --help, this looks like you want the help:
INFO:
    Print info about UF2 download.

Which unfortunately doesn't print anything on how to run it on a file, I think that's a bug, but unrelated to this PR, I'm going to try to flash the file instead of pursuing this unrelated bug and try to get the wifi firmware into a partition :)

@lurch
Copy link
Contributor

lurch commented Jul 23, 2025

I've no opinion on whether we should include this change or not (that's @will-v-pi 's decision to make), but I wonder if you ought to remove the ERROR: unexpected option: --help, this looks like you want the help: message? If I run e.g. git help commit or git commit --help, then both commands appear to show identical output.

@will-v-pi
Copy link
Contributor

Which unfortunately doesn't print anything on how to run it on a file, I think that's a bug, but unrelated to this PR, I'm going to try to flash the file instead of pursuing this unrelated bug and try to get the wifi firmware into a partition :)

You can't run uf2 info on a file - it prints info about the last UF2 download to a device if it failed. To get info from a file just use the info command.

@will-v-pi will-v-pi added this to the 2.3.0 milestone Jul 23, 2025
@will-v-pi
Copy link
Contributor

Also, please target all PRs at the develop branch, not master

@iwanders iwanders force-pushed the add-handling-for--help branch from c58b619 to 7e9e0c3 Compare July 23, 2025 11:20
@iwanders iwanders changed the base branch from master to develop July 23, 2025 11:24
@iwanders
Copy link
Author

I've no opinion on whether we should include this change or not

As always; maintainer's choice, I ran into something that I thought was worth fixing for myself :)

but I wonder if you ought to remove the ERROR: unexpected option: --help, this looks like you want the help: message? If I run e.g. git help commit or git commit --help, then both commands appear to show identical output.

Yeah, maybe we should. Initially I didn't in case someone typo'd a -h command or something, but you are right that it probably makes more sense to not print this. I've removed it, output is now:

./picotool partition info --help
INFO:
    Print the device's partition table.

SYNOPSIS:
    picotool partition info [-m <family_id>] [device-selection]

OPTIONS:
        -m <family_id>
            family ID (will show target partition for said family)

To get info from a file just use the info command.

Ah, perfect, thanks that's indeed what I needed.

Also, please target all PRs at the develop branch, not master

I've changed the target branch. It would be good to include this in the pull request template, that way anyone filing a PR will read this requirement.

@iwanders iwanders force-pushed the add-handling-for--help branch from 7e9e0c3 to 8a243f4 Compare July 23, 2025 11:31
Most binaries used on Linux support the '--help' argument, this
is a convention specified by the [GNU project][1], as well as in
the [clig][2].

Currently, adding `--help` after a failing command gives an error,
following by an note at the end on how to get the help. Actually
getting the help usually involves pressing the up arrow, removing the
erroneous `--help` at the end, moving the cursor to after `picotool`
to insert `help` and then succesfully printing out the help.

This commit adds a new error type to the parser to distinguish
between parse errors, and errors that can be identified as an attempt
to obtain the help. This help error is raised only if an unexpected
argument called `--help` is encountered, or an unexpected option `-h`.

In the `main.cpp` this specific error is now caught and handled on
appropriately, still relying on the outer catch problematic parse
errors, like using command names that don't exist.

[1]: https://www.gnu.org/prep/standards/html_node/Command_002dLine-Interfaces.html
[2]: https://clig.dev/#help
@iwanders
Copy link
Author

I've now also rebased my branch on the develop branch, that should hopefully make the previous pipeline failures go away. In my previous comment I merely changed the target branch but didn't rebase the source completely, I thought it would be fine, but the pipeline failed spectacularly... this should do it 🤞

@lurch
Copy link
Contributor

lurch commented Jul 23, 2025

I've changed the target branch. It would be good to include this in the pull request template, that way anyone filing a PR will read this requirement.

When dcbeb00 eventually gets merged to the master branch, it'll automatically reject any PRs targeting master 🙂

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.

3 participants