Skip to content
This repository has been archived by the owner on Jan 1, 2022. It is now read-only.

takes_value() parameters with default_value() are shown in USAGE like mandatory #86

Open
epage opened this issue Dec 6, 2021 · 5 comments

Comments

@epage
Copy link
Owner

epage commented Dec 6, 2021

Issue by albel727
Friday Jan 05, 2018 at 22:04 GMT
Originally opened as clap-rs/clap#1140


Affected Version of clap

clap 2.29.0

Expected Behavior Summary

When command line parsing fails, a USAGE section is shown. This usage section should NOT contain non-required parameters with default values. Suppose there are two parameters, "required" and "defaulted", and the user didn't specify the required one. The output should be as follows

error: The following required arguments were not provided:
    <required>

USAGE:
    prog [OPTIONS] <required>

For more information try --help

Actual Behavior Summary

Defaulted option parameters are mentioned in parse error help for no particular reason, confusingly looking like they're mandatory, even if they're required(false).

error: The following required arguments were not provided:
    <required>

USAGE:
    prog <required> --defaulted <defaulted>

For more information try --help

Steps to Reproduce the issue

Utilize the following code. Note that if one comments out ".default_value()", the parse error no longer contains the mention of the defaulted parameter, as expected.

Sample Code or Link to Sample Code

    App::new("Test")
        .arg(
            Arg::with_name("required")
                .required(true)
        )
        .arg(
            Arg::with_name("defaulted")
                .takes_value(true)
                .short("d")
                .long("defaulted")
                .default_value("1")
        ).get_matches();
@epage
Copy link
Owner Author

epage commented Dec 6, 2021

Comment by albel727
Friday Jan 05, 2018 at 22:28 GMT


It's particularly annoying that this shadows all other flags. So

    App::new("Test")
        .arg(
            Arg::with_name("required")
                .required(true)
        )
        .arg(
            Arg::with_name("defaulted")
                .takes_value(true)
                .short("d")
                .long("defaulted")
                .default_value("1")
        )
        .arg(
            Arg::with_name("another")
        )
        .get_matches_from(vec!["prog"]);

produces

USAGE:
    prog <required> --defaulted <defaulted>

instead of

USAGE:
    prog [OPTIONS] <required> [another]

@epage
Copy link
Owner Author

epage commented Dec 6, 2021

Comment by kbknapp
Tuesday Jan 09, 2018 at 18:08 GMT


The error messages show "used arguments" i.e. "this possibly what the command you just tried running should have been run"

But yes, defaults get thrown in there too. I can do some work to remove default values from error messages. This wouldn't however "turn off" the shadowing. With that fix

$ prog another
error: missing required [..snip]

USAGE:
    prog <required> --defaulted <defaulted> [another]

Would become

$ prog another
error: missing required [..snip]

USAGE:
    prog <required> [another]

I'm open to adding an option to turn off this "smart usage" so that the error would become just the default:

$ prog another
error: missing required [..snip]

USAGE:
    prog [FLAGS] [OPTIONS] <required>

(you can already kind of do this by just supplying your own usage string, which will get used no matter what.)

@epage
Copy link
Owner Author

epage commented Dec 6, 2021

Comment by kbknapp
Tuesday Jan 09, 2018 at 18:08 GMT


If someone wants to add this setting to disable the "smart usage" I'd be happy to mentor it. Removing the defaults from the usage string is probably more complicated than just adding this setting.

@epage
Copy link
Owner Author

epage commented Dec 6, 2021

Comment by albel727
Wednesday Jan 10, 2018 at 20:33 GMT


I see. I'll consider the possible ways to proceed from here, after I take a look at the clap sources when I'm done with other things. For the time being, I have another alternative to posit.

How hard would it be to, at least, make the defaulted but non-required arguments be printed in square brackets, so as to convey their non-mandatory nature? I.e. something like

USAGE:
    prog <required> [--defaulted <defaulted>] [another]

Or do you think that this would violate user's expectations, making them believe that they have to put "--defaulted" in square brackets in order to use it?

@epage
Copy link
Owner Author

epage commented Dec 6, 2021

Comment by kbknapp
Monday Jan 15, 2018 at 19:36 GMT


I.e. something like

It would be fine, but almost as much work as simply not printing the defaults (which is a slightly better solution IMO).

In the source for either of these two fixes, when clap is printing the usage string, it doesn't know if something is a default value or not, it just sees an argument was used (used by user, or used by default). So it would require re-looping through the used arguments to see if they have a default, and if so if the value that was used was in fact the default.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

1 participant