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

v3 App Options no longer work on subcommand arguments #1915

Closed
2 tasks done
publicarray opened this issue May 8, 2020 · 5 comments
Closed
2 tasks done

v3 App Options no longer work on subcommand arguments #1915

publicarray opened this issue May 8, 2020 · 5 comments
Labels
C-bug Category: Updating dependencies

Comments

@publicarray
Copy link

Make sure you completed the following tasks

Code

use clap::{App, Arg, AppSettings};

fn main() {
    let cli = App::new("foo")
        .setting(AppSettings::SubcommandRequired)
        .arg(Arg::with_name("v")
                .short('v')
                .multiple(true)
                .about("Sets the level of verbosity"))
        .subcommand(App::new("bar")
                .arg(Arg::with_name("baz")
                        .long("baz")
                    )).get_matches();

    let log_level = cli.occurrences_of("v");
    println!("{}", log_level);
    if let Some(bar) = cli.subcommand_matches("bar") {
        if bar.is_present("baz") {
            println!("Hello World");
        }
    }
}

Steps to reproduce the issue

  1. Run cargo run -- -v bar --baz error: Found argument '--baz' which wasn't expected, or isn't valid in this context

Version

  • Rust: rustc 1.44.0-nightly
  • Clap: master

Actual Behavior Summary

  1. Run cargo run -- bar = 0 (expected)
  2. Run cargo run -- bar --baz = 0 Hello World (expected)
  3. Run cargo run -- -v bar = 1 (expected)
  4. Run cargo run -- -v bar --baz error: Found argument '--baz' which wasn't expected, or isn't valid in this context

I'm using clap-rs in https://github.com/publicarray/BunnyCLI

Expected Behavior Summary

From run number 4 the output should be:

1
Hello World

Additional context

Debug output

Compile clap with debug feature:

[dependencies]
clap = { version = "*", features = ["debug"] }

The output may be very long, so feel free to link to a gist or attach a text file

Debug Output

 Running `target/debug/my-test -v bar --baz`

[ clap::build::app] App::_do_parse
[ clap::build::app] App::_build
[ clap::build::app] App::_derive_display_order:foo
[ clap::build::app] App::_derive_display_order:bar
[ clap::build::app] App::_create_help_and_version
[ clap::build::app] App::_create_help_and_version: Building --help
[ clap::build::app] App::_create_help_and_version: Building --version
[ clap::build::app] App::_create_help_and_version: Building help
[ clap::build::app] App::_debug_asserts
[ clap::build::arg] Arg::_debug_asserts:v
[ clap::build::arg] Arg::_debug_asserts:help
[ clap::build::arg] Arg::_debug_asserts:version
[ clap::parse::parser] Parser::get_matches_with
[ clap::parse::parser] Parser::_build
[ clap::parse::parser] Parser::_verify_positionals
[ clap::parse::parser] Parser::get_matches_with: Begin parsing '"-v"' ([45, 118])
[ clap::parse::parser] Parser::is_new_arg: "-v":NotFound
[ clap::parse::parser] Parser::is_new_arg: arg_allows_tac=false
[ clap::parse::parser] Parser::is_new_arg: - found
[ clap::parse::parser] Parser::is_new_arg: starts_new_arg=true
[ clap::parse::parser] Parser::possible_subcommand: arg="-v"
[ clap::parse::parser] Parser::get_matches_with: possible_sc=false, sc=None
[ clap::parse::parser] Parser::parse_short_arg: full_arg="-v"
[ clap::parse::parser] Parser::parse_short_arg:iter:v
[ clap::parse::parser] Parser::parse_short_arg:iter:v: Found valid opt or flag
[ clap::util::argstr] ArgSplit::next: self=ArgSplit { sep: [118, 0, 0, 0], sep_len: 1, val: [118], pos: 0 }
[ clap::parse::parser] Parser::parse_short_arg:iter:v: i=1, arg_os="v"
[ clap::parse::parser] Parser::parse_opt; opt=v, val=None
[ clap::parse::parser] Parser::parse_opt; opt.settings=ArgFlags(MULTIPLE_OCC | TAKES_VAL | DELIM_NOT_SET | MULTIPLE_VALS)
[ clap::parse::parser] Parser::parse_opt; Checking for val...
[ clap::parse::parser] None
[ clap::parse::arg_matcher] ArgMatcher::inc_occurrence_of: arg=v
[ clap::parse::arg_matcher] ArgMatcher::inc_occurrence_of: first instance
[ clap::parse::parser] groups_for_arg: name=v
[ clap::parse::parser] Parser::parse_opt: More arg vals required...
[ clap::parse::parser] Parser::get_matches_with: After parse_short_arg Opt(v)
[ clap::parse::parser] Parser::maybe_inc_pos_counter: arg = v
[ clap::parse::parser] Parser::maybe_inc_pos_counter: is it positional?
[ clap::parse::parser] No
[ clap::parse::parser] groups_for_arg: name=v
[ clap::parse::parser] Parser::get_matches_with: Begin parsing '"bar"' ([98, 97, 114])
[ clap::parse::parser] Parser::is_new_arg: "bar":Opt(v)
[ clap::parse::parser] Parser::is_new_arg: arg_allows_tac=false
[ clap::parse::parser] Parser::is_new_arg: probably value
[ clap::parse::parser] Parser::is_new_arg: starts_new_arg=false
[ clap::parse::parser] Parser::add_val_to_arg; arg=v, val="bar"
[ clap::parse::parser] Parser::add_val_to_arg; trailing_vals=false, DontDelimTrailingVals=false
[ clap::parse::parser] Parser::add_single_val_to_arg: adding val..."bar"
[ clap::parse::parser] groups_for_arg: name=v
[ clap::parse::arg_matcher] ArgMatcher::needs_more_vals: o=v
[ clap::parse::parser] Parser::get_matches_with: Begin parsing '"--baz"' ([45, 45, 98, 97, 122])
[ clap::parse::parser] Parser::is_new_arg: "--baz":Opt(v)
[ clap::parse::parser] Parser::is_new_arg: arg_allows_tac=false
[ clap::parse::parser] Parser::is_new_arg: -- found
[ clap::parse::parser] Parser::is_new_arg: starts_new_arg=true
[ clap::parse::parser] Parser::parse_long_arg
[ clap::parse::parser] Parser::parse_long_arg: Does it contain '='...
[ clap::parse::parser] No
[ clap::parse::parser] Parser::parse_long_arg: Didn't match anything
[ clap::parse::parser] Parser::did_you_mean_error: arg=baz
[ clap::parse::parser] Parser::did_you_mean_error: longs=["help", "version"]
[ clap::build::app] App::_build
[ clap::build::app] App::_derive_display_order:bar
[ clap::build::app] App::_create_help_and_version
[ clap::build::app] App::_create_help_and_version: Building --help
[ clap::build::app] App::_create_help_and_version: Building --version
[ clap::build::app] App::_debug_asserts
[ clap::build::arg] Arg::_debug_asserts:baz
[ clap::build::arg] Arg::_debug_asserts:help
[ clap::build::arg] Arg::_debug_asserts:version
[ clap::output::usage] Usage::create_usage_with_title
[ clap::output::usage] Usage::create_usage_no_title
[ clap::output::usage] Usage::create_smart_usage
[ clap::output::usage] Usage::get_required_usage_from: incls=[v], matcher=false, incl_last=true
[ clap::output::usage] Usage::get_required_usage_from:iter:v
[ clap::output::usage] Usage::get_required_usage_from: ret_val=["-v ..."]
[ clap::build::app] App::color: Color setting...
[ clap::build::app] Auto
[ clap::output::fmt] is_a_tty: stderr=true
error: Found argument '--baz' which wasn't expected, or isn't valid in this context

Did you mean to put '--baz' after the subcommand 'bar'?

If you tried to supply --baz as a PATTERN use -- --baz

USAGE:
my-test -v ...

For more information try --help

@publicarray publicarray added the C-bug Category: Updating dependencies label May 8, 2020
@CreepySkeleton
Copy link
Contributor

This is because bar is considered as a value for -v instead of subcommand. See #1721, #1031, and #1834.

TL;DR: use SubcommandPrecedenceOverArg settings.

Personally, I would recommend you to redesign the CLI. This kind of "values vs subcommand" may cause more harm than goon in long term.

@publicarray
Copy link
Author

Thanks very @CreepySkeleton, that works nicely & Thanks for the advice. Any ideas on how to design it better ?

goon

I'm going to have some wine now 🤣

@CreepySkeleton
Copy link
Contributor

Well, if you truly intend -v to take value, I recommend to go cargo --features "f1 f2" way. Can be achieved via value_delimiter(" ") and require_delimiter(true).

But I bet your intention was to allow multiple number of occurrences, not values. multiple(true) means both multiple values (requiring at least one value) and multiple occurrences while you only need the latter. Use multiple_occurrences(true) and you'll live happily ever after.

goon

I must have been a comedian in a previous life, don't you think? Even when my mind isn't up to it, my muscle memory knows better and bony fingers hit the right button.

Unfortunately, I can't share the wine with you. Skeletons don't have much of taste, after all.

@publicarray
Copy link
Author

Thank you! I'm going to pick live happily ever after multiple_occurrences(true). Your comment does have lots of useful information and I did not find this in the manual. Maybe this can be included or maybe I need to get my eye sight checked.

Haha, well played..

True, You could give it go but it might stain your ribs: https://www.youtube.com/watch?v=1fzXmJyolfY&t=33

@pksunkara
Copy link
Member

We are still working on changelog and documentation. You are not supposed to use v3 yet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-bug Category: Updating dependencies
Projects
None yet
Development

No branches or pull requests

3 participants