Skip to content
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

default_value() and multiple(true) interact in surprising ways. #1056

Closed
Screwtapello opened this issue Sep 28, 2017 · 2 comments
Closed

default_value() and multiple(true) interact in surprising ways. #1056

Screwtapello opened this issue Sep 28, 2017 · 2 comments
Labels
A-parsing Area: Parser's logic and needs it changed somehow. C-bug Category: Updating dependencies
Milestone

Comments

@Screwtapello
Copy link

Rust Version

rustc 1.20.0 (f3d6973f4 2017-08-27)

Affected Version of clap

clap 2.26.2

Steps to Reproduce the issue

I want to write a program that's a little bit like ssh: it does some setup, then runs the rest of the command-line arguments as a new process. If there are no other arguments, it just runs a shell. Looking at the clap documentation, I came up with the following pattern:

extern crate clap;

fn main() {
    let matches = clap::App::new("claptest")
        .setting(clap::AppSettings::TrailingVarArg)
        .arg(clap::Arg::with_name("command")
            .multiple(true)
            .default_value("/bin/sh")
        )
        .get_matches();

    let command: Vec<_> = matches.values_of_os("command").unwrap().collect();

    println!("Command to run: {:?}", command);
}                                                                               

If I build this and run it with no arguments, I get the default, just as I wanted:

$ ./target/debug/claptest 
Command to run: ["/bin/sh"]

If I give it a different command to run, I get the default appended to the command I gave:

$ ./target/debug/claptest foo bar
Command to run: ["foo", "bar", "/bin/sh"]

If there's an explicit value on the command-line, I'd expect that to replace the default, not extend it:

$ ./target/debug/claptest foo bar
Command to run: ["foo", "bar"]

Workarounds

If I don't use .default_value(), I can manually apply the default later, but of course then it doesn't show up in the --help output with all the other defaults.

.occurrences_of() returns 0 if only the default is present, 1 if there's one explicit argument, etc. I could do something like:

let command: Vec<_> = if matches.occurrences_of("command") > 0 {
    matches.values_of_os("command").unwrap().take(matches.occurrences_of("command"))
} else {
    matches.values_of_os("command").unwrap()
}.collect();

...but man, that's a mouthful.

@kbknapp
Copy link
Member

kbknapp commented Oct 4, 2017

This is a bug, thanks for reporting!

I'd be willing to mentor someone to fix this, which should be a super quick fix if someone wants an easy PR. Otherwise I can try and knock it out this week once I get a little caught up.

If anyone is interested, the code to potentially fix this issue is here. You'd simply need to ensure there are no values before adding the defaults.

@kbknapp kbknapp added A-parsing Area: Parser's logic and needs it changed somehow. D: easy C-bug Category: Updating dependencies labels Oct 4, 2017
@kbknapp
Copy link
Member

kbknapp commented Oct 4, 2017

Duplicate of #1050

@kbknapp kbknapp added this to the 2.27.0 milestone Oct 12, 2017
@kbknapp kbknapp marked this as a duplicate of #1050 Oct 12, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-parsing Area: Parser's logic and needs it changed somehow. C-bug Category: Updating dependencies
Projects
None yet
Development

No branches or pull requests

2 participants