Clap: Positional arguments don't work with cargo plugins

Created on 28 Apr 2018  路  3Comments  路  Source: clap-rs/clap

Rust Version

rustc 1.27.0-nightly (056f589fb 2018-04-07)

Affected Version of clap

clap 2.31.2

Expected Behavior Summary

The following example works perfectly; I expect invoking this program via cargo disassemble main to work in the same way.

$ ~/.cargo/bin/cargo-disassemble main

Actual Behavior Summary

$ cargo disassemble main
error: Found argument 'main' which wasn't expected, or isn't valid in this context

USAGE:
    cargo-disassemble [FLAGS] [OPTIONS] [function]

For more information try --help

Steps to Reproduce the issue

$ cargo install cargo-disassemble
$ cargo disassemble main # fails
$ ~/.cargo/bin/cargo-disassemble main # succeeds

Options and Flags work, but Args do not.

Sample Code or Link to Sample Code

https://github.com/AdamNiederer/cargo-disassemble/blob/master/src/main.rs#L52
https://github.com/AdamNiederer/cargo-disassemble/blob/master/src/main.rs#L55

Debug output

(Used via structopt)

Most helpful comment

Direct translation of @kbknapp example:

#[macro_use]
extern crate structopt;

use structopt::StructOpt;

#[derive(StructOpt, Debug)]
struct Options {
    #[structopt(help = "The name of the function to be decompiled")]
    function: Option<String>,
    // ...
}

#[derive(StructOpt, Debug)]
#[structopt(
    name = "cargo-disassemble",
    bin_name = "cargo",
    about = "Easy disassembly of Rust code."
)]
enum Cargo {
    #[structopt(name = "disassemble")]
    Disassemble(Options)
}

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

All 3 comments

I'm going to close this and ping @TeXitoi (structopt author), because I'm not actually 100% sure how cargo subcommands are constructed using structopt short of using the structopt raw(...) methods.

Here's you do it with vanilla clap:

App::new("cargo-disassemble")
    .bin_name("cargo")
    .setting(AppSettings::SubcommandRequiredElseHelp)
    .subcommand(SubCommand::with_name("disassemble")
        // add args
    );

And then it's called $ cargo disassemble <args>... or $ cargo-disassemble disassemble <args>...

Direct translation of @kbknapp example:

#[macro_use]
extern crate structopt;

use structopt::StructOpt;

#[derive(StructOpt, Debug)]
struct Options {
    #[structopt(help = "The name of the function to be decompiled")]
    function: Option<String>,
    // ...
}

#[derive(StructOpt, Debug)]
#[structopt(
    name = "cargo-disassemble",
    bin_name = "cargo",
    about = "Easy disassembly of Rust code."
)]
enum Cargo {
    #[structopt(name = "disassemble")]
    Disassemble(Options)
}

fn main() {
    let Cargo::Disassemble(opt) = Cargo::from_args();
    println!("{:?}", opt);
}
Was this page helpful?
0 / 5 - 0 ratings

Related issues

joshtriplett picture joshtriplett  路  75Comments

XAMPPRocky picture XAMPPRocky  路  17Comments

kbknapp picture kbknapp  路  22Comments

CAD97 picture CAD97  路  21Comments

ruabmbua picture ruabmbua  路  17Comments