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

Last argument needs to be quoted #1344

Closed
marceloboeira opened this issue Sep 24, 2018 · 2 comments
Closed

Last argument needs to be quoted #1344

marceloboeira opened this issue Sep 24, 2018 · 2 comments

Comments

@marceloboeira
Copy link

Rust Version

rustc 1.27.0 (3eda71b00 2018-06-19)

Affected Version of clap

"checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e"

Expected Behavior Summary

My command line tool is supposed to work like this
foo -u <user> <command>
e.g.:
foo -u jack echo s
foo -u paul ls -al

So, I need to get options such as user, but the <command> itself, I need to be the rest of the args.

Actual Behavior Summary

The code below, results on a behavior where I can't get the value of <command> unless is quoted:

foo -u jack echo s -> error: Found argument 's' which wasn't expected, or isn't valid in this context

whereas:
foo -u jack 'echo s' works fine.

Is there anyway of avoiding the quotes?

Sample Code or Link to Sample Code

    let matches = App::new("foo")
                          .version("0.1")
                          .arg(Arg::with_name("user")
                               .short("u")
                               .long("user")
                               .required(true)
                               .takes_value(true))
                          .arg(Arg::with_name("command")
                               .help("The command to run")
                               .required(true)
                               .takes_value(true)).get_matches();
@marceloboeira
Copy link
Author

marceloboeira commented Mar 25, 2019

Any updates? Is the project still maintained?

@marceloboeira
Copy link
Author

marceloboeira commented Mar 25, 2019

If it's of anyones interest:

By default, clap will only parse any argument once. This means that in -u jack echo s, it will parse -u jack as the "user" option, echo as the "command" argument, and have an argument s that it doesn't know what to do with (hence it "wasn't expected").

I'm assuming you want all of the non-option arguments instead of just one, in which case setting .multiple(true) on your non-option argument ("command") is what you want. In that case, it will parse all remaining, non-option arguments as "command", and give you a list back with each of the arguments (which you can deal with as you please):

let matches = App::new("foo")
    .version("0.1")
    .arg(
        Arg::with_name("user")
            .short("u")
            .long("user")
            .required(true)
            .takes_value(true),
    )
    .arg(
        Arg::with_name("command")
            .help("The command to run")
            .required(true)
            .takes_value(true)
            .multiple(true),
    )
    // parse as if program ran as:   foo -u jack echo s
    .get_matches_from(&["foo", "-u", "jack", "echo", "s"]);

// get command arguments
let command: Vec<&str> = matches.values_of("command").unwrap().collect();
println!("{:?}", command); // ["echo", "s"]

More info: https://stackoverflow.com/questions/55345730/how-can-i-prevent-the-last-argument-from-needing-to-be-quoted-with-clap/55345899#55345899

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

No branches or pull requests

1 participant