Skip to content
This repository has been archived by the owner on Sep 14, 2023. It is now read-only.

confusing failure mode when usage and option sections are inconsistent #226

Open
xTibor opened this issue Aug 4, 2017 · 2 comments
Open

Comments

@xTibor
Copy link

xTibor commented Aug 4, 2017

When the following test program is executed with --output out --input in arguments, the values switch places, the input variable in Args gets "out" and the output one gets the "in" value.

I encountered this issue with 0.8.1 and the latest nightly (rustc 1.21.0-nightly).

Test program

extern crate docopt;
#[macro_use]
extern crate serde_derive;

use docopt::Docopt;

const USAGE: &'static str = "
Usage:
    xxxx [--input <input>] [--output <output>]
    xxxx --help

Options:
    -i, --input   Input file
    -o, --output  Output file
    -h, --help    Display this message
";

#[derive(Debug, Deserialize)]
struct Args {
    arg_input: Option<String>,
    arg_output: Option<String>,
}

fn main() {
    let args: Args = Docopt::new(USAGE)
        .and_then(|d| d.deserialize())
        .unwrap_or_else(|e| e.exit());

    println!("{:?}", args);
}

Result

Args { arg_input: Some("out"), arg_output: Some("in") }

Expected result

Args { arg_input: Some("in"), arg_output: Some("out") }

@BurntSushi
Copy link
Member

I don't think there's any bug here, but the failure mode is obviously bad.

There are two errors in your example code. Firstly, your option description section needs to indicate that a flag takes an argument. So instead of -i, --input, you'd write -i, --input <input>. Secondly, your members in your Args struct have an arg prefix, but they are flags, which means they need a flag prefix. arg is for positional arguments. This behavior is documented on the ArgvMap::deserialize method.

Ideas on how to improve the failure modes here would be appreciated. It seems like the least we could do is report the inconsistency between the flag definition --input <input> in the USAGE section and the inconsistent -i, --input definition in the option description section.

@BurntSushi BurntSushi changed the title Arguments parsed incorrectly confusing failure mode when usage and option sections are inconsistent Aug 4, 2017
@xTibor
Copy link
Author

xTibor commented Aug 4, 2017

Oh, sorry for mixing these things up in the example. I just assumed something's wrong with the crate because it acted weird in this case and didn't throw errors at me (like it does for the missing args).

drozdziak1 pushed a commit to drozdziak1/althea_rs that referenced this issue May 14, 2018
As outlined in this bug docopt/docopt.rs#226
Docopt is rather specific about flags versus positional arguments. In
our case we had positional arguments that we where using as flags. This
created some very confusing behavior where you you could reorder the flags
and get a arcane looking config error because 'linux' (the platform arg)
was passed as the config arg. If you look carefully at the example USAGE
in the Docopt README https://github.com/docopt/docopt you see that all
flags not only require the Args strut but also the use of the = sign.

This patch corrects these problems and allows flags to work as expected
jkilpatr added a commit to althea-net/rita that referenced this issue Feb 7, 2020
As outlined in this bug docopt/docopt.rs#226
Docopt is rather specific about flags versus positional arguments. In
our case we had positional arguments that we where using as flags. This
created some very confusing behavior where you you could reorder the flags
and get a arcane looking config error because 'linux' (the platform arg)
was passed as the config arg. If you look carefully at the example USAGE
in the Docopt README https://github.com/docopt/docopt you see that all
flags not only require the Args strut but also the use of the = sign.

This patch corrects these problems and allows flags to work as expected
jkilpatr added a commit to althea-net/rita that referenced this issue Feb 7, 2020
As outlined in this bug docopt/docopt.rs#226
Docopt is rather specific about flags versus positional arguments. In
our case we had positional arguments that we where using as flags. This
created some very confusing behavior where you you could reorder the flags
and get a arcane looking config error because 'linux' (the platform arg)
was passed as the config arg. If you look carefully at the example USAGE
in the Docopt README https://github.com/docopt/docopt you see that all
flags not only require the Args strut but also the use of the = sign.

This patch corrects these problems and allows flags to work as expected
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

2 participants