TeXitoi / structopt

Parse command line arguments by defining a struct.
Other
2.7k stars 149 forks source link

Parser too greedy, eats param twice #508

Closed kristof-mattei closed 2 years ago

kristof-mattei commented 2 years ago

Is there a way to tell structopt: Parse argument until you hit something you don't understand, and put the rest in rest?

For example:

use structopt::StructOpt;

/// A basic example
#[derive(StructOpt, Debug)]
struct Opt {
    #[structopt(short="c")]
    debug: bool,

    rest: Vec<String>
}

fn main() {
    let opt = Opt::from_args();
    println!("{:#?}", opt);
}

This is how the documentation tells me to specify a raw string. However, while debugging I noticed that the following doesn't work: greedy -c sh -c foo The result is error: The argument '-c' was provided more than once, but cannot be used multiple times

The problem is less obvious, but still present if we don't provide our initial -c: greedy -c sh -c foo yields

Opt {
    debug: true,
    rest: [
        "sh",
        "bash",
    ],
}

Whoops, the -c of sh is now our flag.

Now, I can mitigate both problems by using the -- in between. HOWEVER, since the library I'm updating is being used by people I cannot influence I have to support both -- and 'this is the set of parameters you can expect, go over it, once, like getopts_long, and the rest is varargs'.

Any way I can get the latter behavior our of structopts?

kristof-mattei commented 2 years ago

And I'm too tired to be properly reading documentation.

#[structopt(
    setting = AppSettings::TrailingVarArg,
)]

was the trick. Thanks for the awesome library.

I hope my issue can serve the search engines for other people =)