When an argument is marked as #[clap(global = true)], it is correctly propagated down to the sub-command if there is any, but not to sub-commands' own sub-commands.
Here is a sample code:
// The following command doesn't work though it should:
//
// > cargo run -- test --required "hello" --not-required "world"
use clap::Clap;
#[derive(Clap, Debug)]
struct Opts {
#[clap(global = true, long)]
global_flag: bool,
#[clap(global = true, long)]
global_str: Option<String>,
#[clap(subcommand)]
subcommand: SubCommand
}
#[derive(Clap, Debug)]
enum SubCommand {
Test(TestSubCommand)
}
#[derive(Clap, Debug)]
struct TestSubCommand {
#[clap(global = true, long)]
sub_flag: bool,
#[clap(global = true, long)]
sub_str: Option<String>,
#[clap(subcommand)]
subcommand: SubSubCommand
}
#[derive(Clap, Debug)]
enum SubSubCommand {
Test(TestSubSubCommand)
}
#[derive(Clap, Debug)]
struct TestSubSubCommand {}
fn main() {
println!("{:?}", Opts::parse());
}
### Steps to reproduce the issue
1. Run `cargo run -- test test --global-flag --global-str "hello" --sub-flag --sub-str "world"`
2. Wrong output is shown.
### Version
* **Rust**: `rustc 1.45.0 (5c1f21c3b 2020-07-13)` & `rustc 1.47.0-nightly (6c8927b0c 2020-07-26)`
* **Clap**: `3.0.0-beta.1`
### Actual Behavior Summary
Program outputs the following when running it with ``cargo run -- test test --global-flag --global-str "hello" --sub-flag --sub-str "world"``:
Opts { global_flag: true, global_str: Some("hello"), subcommand: Test(TestSubCommand { sub_flag: false, sub_str: None, subcommand: Test(TestSubSubCommand) }) }
### Expected Behavior Summary
Program *should* output the following:
Opts { global_flag: true, global_str: Some("hello"), subcommand: Test(TestSubCommand { sub_flag: true, sub_str: Some("world"), subcommand: Test(TestSubSubCommand) }) }
### Debug output
Compiling clap_derive v3.0.0-beta.1
Compiling clap v3.0.0-beta.1
Compiling clap-demo v0.1.0 (/mnt/c/Temp/__wsltemp/clap-demo)
Finished dev [unoptimized + debuginfo] target(s) in 27.72s
Running `target/debug/clap-demo test test --global-flag --global-str hello --sub-flag --sub-str world`
[ clap::build::app] App::_do_parse
[ clap::build::app] App::_build
[ clap::build::app] App::_derive_display_order:clap-demo
[ clap::build::app] App::_derive_display_order:test
[ clap::build::app] App::_derive_display_order:test
[ 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:global-flag
[ clap::build::arg] Arg::_debug_asserts:global-str
[ 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 '"test"' ([116, 101, 115, 116])
[ clap::parse::parser] Parser::is_new_arg: "test":NotFound
[ 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::possible_subcommand: arg="test"
[ clap::parse::parser] Parser::get_matches_with: possible_sc=true, sc=Some("test")
[ clap::parse::parser] Parser::parse_subcommand
[ clap::output::usage] Usage::get_required_usage_from: incls=[], matcher=false, incl_last=true
[ clap::output::usage] Usage::get_required_usage_from: ret_val=[]
[ clap::build::app] App::_propagate:clap-demo
[ clap::build::app] App::_build
[ clap::build::app] App::_derive_display_order:test
[ clap::build::app] App::_derive_display_order:test
[ 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:sub-flag
[ clap::build::arg] Arg::_debug_asserts:sub-str
[ clap::build::arg] Arg::_debug_asserts:global-flag
[ clap::build::arg] Arg::_debug_asserts:global-str
[ clap::build::arg] Arg::_debug_asserts:help
[ clap::build::arg] Arg::_debug_asserts:version
[ clap::parse::parser] Parser::parse_subcommand: About to parse sc=test
[ 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 '"test"' ([116, 101, 115, 116])
[ clap::parse::parser] Parser::is_new_arg: "test":NotFound
[ 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::possible_subcommand: arg="test"
[ clap::parse::parser] Parser::get_matches_with: possible_sc=true, sc=Some("test")
[ clap::parse::parser] Parser::parse_subcommand
[ clap::output::usage] Usage::get_required_usage_from: incls=[], matcher=false, incl_last=true
[ clap::output::usage] Usage::get_required_usage_from: ret_val=[]
[ clap::build::app] App::_propagate:test
[ clap::build::app] App::_build
[ clap::build::app] App::_derive_display_order:test
[ 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:sub-flag
[ clap::build::arg] Arg::_debug_asserts:sub-str
[ clap::build::arg] Arg::_debug_asserts:global-flag
[ clap::build::arg] Arg::_debug_asserts:global-str
[ clap::build::arg] Arg::_debug_asserts:help
[ clap::build::arg] Arg::_debug_asserts:version
[ clap::parse::parser] Parser::parse_subcommand: About to parse sc=test
[ 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 '"--global-flag"' ([45, 45, 103, 108, 111, 98, 97, 108, 45, 102, 108, 97, 103])
[ clap::parse::parser] Parser::is_new_arg: "--global-flag":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="--global-flag"
[ clap::parse::parser] Parser::get_matches_with: possible_sc=false, sc=None
[ 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: Found valid opt or flag '--global-flag'
[ clap::parse::parser] Parser::check_for_help_and_version_str
[ clap::parse::parser] Parser::check_for_help_and_version_str: Checking if --"global-flag" is help or version...
[ clap::parse::parser] Neither
[ clap::parse::parser] Parser::parse_flag
[ clap::parse::arg_matcher] ArgMatcher::inc_occurrence_of: arg=global-flag
[ clap::parse::arg_matcher] ArgMatcher::inc_occurrence_of: first instance
[ clap::parse::parser] groups_for_arg: name=global-flag
[ clap::parse::parser] Parser::get_matches_with: After parse_long_arg Flag(global-flag)
[ clap::parse::parser] Parser::maybe_inc_pos_counter: arg = global-flag
[ clap::parse::parser] Parser::maybe_inc_pos_counter: is it positional?
[ clap::parse::parser] No
[ clap::parse::parser] groups_for_arg: name=global-flag
[ clap::parse::parser] Parser::get_matches_with: Begin parsing '"--global-str"' ([45, 45, 103, 108, 111, 98, 97, 108, 45, 115, 116, 114])
[ clap::parse::parser] Parser::is_new_arg: "--global-str":Flag(global-flag)
[ 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="--global-str"
[ clap::parse::parser] Parser::get_matches_with: possible_sc=false, sc=None
[ 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: Found valid opt or flag '--global-str '
[ clap::parse::parser] Parser::parse_opt; opt=global-str, val=None
[ clap::parse::parser] Parser::parse_opt; opt.settings=ArgFlags(TAKES_VAL | DELIM_NOT_SET)
[ clap::parse::parser] Parser::parse_opt; Checking for val...
[ clap::parse::parser] None
[ clap::parse::arg_matcher] ArgMatcher::inc_occurrence_of: arg=global-str
[ clap::parse::arg_matcher] ArgMatcher::inc_occurrence_of: first instance
[ clap::parse::parser] groups_for_arg: name=global-str
[ clap::parse::parser] Parser::parse_opt: More arg vals required...
[ clap::parse::parser] Parser::get_matches_with: After parse_long_arg Opt(global-str)
[ clap::parse::parser] Parser::maybe_inc_pos_counter: arg = global-str
[ clap::parse::parser] Parser::maybe_inc_pos_counter: is it positional?
[ clap::parse::parser] No
[ clap::parse::parser] groups_for_arg: name=global-str
[ clap::parse::parser] Parser::get_matches_with: Begin parsing '"hello"' ([104, 101, 108, 108, 111])
[ clap::parse::parser] Parser::is_new_arg: "hello":Opt(global-str)
[ 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=global-str, val="hello"
[ clap::parse::parser] Parser::add_val_to_arg; trailing_vals=false, DontDelimTrailingVals=false
[ clap::parse::parser] Parser::add_single_val_to_arg: adding val..."hello"
[ clap::parse::parser] groups_for_arg: name=global-str
[ clap::parse::arg_matcher] ArgMatcher::needs_more_vals: o=global-str
[ clap::parse::parser] Parser::get_matches_with: Begin parsing '"--sub-flag"' ([45, 45, 115, 117, 98, 45, 102, 108, 97, 103])
[ clap::parse::parser] Parser::is_new_arg: "--sub-flag":ValuesDone(global-str)
[ clap::parse::parser] Parser::possible_subcommand: arg="--sub-flag"
[ clap::parse::parser] Parser::get_matches_with: possible_sc=false, sc=None
[ 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: Found valid opt or flag '--sub-flag'
[ clap::parse::parser] Parser::check_for_help_and_version_str
[ clap::parse::parser] Parser::check_for_help_and_version_str: Checking if --"sub-flag" is help or version...
[ clap::parse::parser] Neither
[ clap::parse::parser] Parser::parse_flag
[ clap::parse::arg_matcher] ArgMatcher::inc_occurrence_of: arg=sub-flag
[ clap::parse::arg_matcher] ArgMatcher::inc_occurrence_of: first instance
[ clap::parse::parser] groups_for_arg: name=sub-flag
[ clap::parse::parser] Parser::get_matches_with: After parse_long_arg Flag(sub-flag)
[ clap::parse::parser] Parser::maybe_inc_pos_counter: arg = sub-flag
[ clap::parse::parser] Parser::maybe_inc_pos_counter: is it positional?
[ clap::parse::parser] No
[ clap::parse::parser] groups_for_arg: name=sub-flag
[ clap::parse::parser] Parser::get_matches_with: Begin parsing '"--sub-str"' ([45, 45, 115, 117, 98, 45, 115, 116, 114])
[ clap::parse::parser] Parser::is_new_arg: "--sub-str":Flag(sub-flag)
[ 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="--sub-str"
[ clap::parse::parser] Parser::get_matches_with: possible_sc=false, sc=None
[ 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: Found valid opt or flag '--sub-str '
[ clap::parse::parser] Parser::parse_opt; opt=sub-str, val=None
[ clap::parse::parser] Parser::parse_opt; opt.settings=ArgFlags(TAKES_VAL | DELIM_NOT_SET)
[ clap::parse::parser] Parser::parse_opt; Checking for val...
[ clap::parse::parser] None
[ clap::parse::arg_matcher] ArgMatcher::inc_occurrence_of: arg=sub-str
[ clap::parse::arg_matcher] ArgMatcher::inc_occurrence_of: first instance
[ clap::parse::parser] groups_for_arg: name=sub-str
[ clap::parse::parser] Parser::parse_opt: More arg vals required...
[ clap::parse::parser] Parser::get_matches_with: After parse_long_arg Opt(sub-str)
[ clap::parse::parser] Parser::maybe_inc_pos_counter: arg = sub-str
[ clap::parse::parser] Parser::maybe_inc_pos_counter: is it positional?
[ clap::parse::parser] No
[ clap::parse::parser] groups_for_arg: name=sub-str
[ clap::parse::parser] Parser::get_matches_with: Begin parsing '"world"' ([119, 111, 114, 108, 100])
[ clap::parse::parser] Parser::is_new_arg: "world":Opt(sub-str)
[ 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=sub-str, val="world"
[ clap::parse::parser] Parser::add_val_to_arg; trailing_vals=false, DontDelimTrailingVals=false
[ clap::parse::parser] Parser::add_single_val_to_arg: adding val..."world"
[ clap::parse::parser] groups_for_arg: name=sub-str
[ clap::parse::arg_matcher] ArgMatcher::needs_more_vals: o=sub-str
[ clap::parse::parser] Parser::remove_overrides
[ clap::parse::parser] Parser::remove_overrides:iter:global-flag
[ clap::parse::parser] Parser::remove_overrides:iter:global-str
[ clap::parse::parser] Parser::remove_overrides:iter:sub-flag
[ clap::parse::parser] Parser::remove_overrides:iter:sub-str
[ clap::parse::validator] Validator::validate
[ clap::parse::parser] Parser::add_defaults
[ clap::parse::parser] Parser::add_defaults:iter:sub-str:
[ clap::parse::parser] Parser::add_value: doesn't have conditional defaults
[ clap::parse::parser] Parser::add_value:iter:sub-str: doesn't have default vals
[ clap::parse::parser] Parser::add_defaults:iter:global-str:
[ clap::parse::parser] Parser::add_value: doesn't have conditional defaults
[ clap::parse::parser] Parser::add_value:iter:global-str: doesn't have default vals
[ clap::parse::validator] Validator::validate_conflicts
[ clap::parse::validator] Validator::validate_exclusive
[ clap::parse::validator] Validator::validate_exclusive:iter:global-flag
[ clap::parse::validator] Validator::validate_exclusive:iter:global-str
[ clap::parse::validator] Validator::validate_exclusive:iter:sub-flag
[ clap::parse::validator] Validator::validate_exclusive:iter:sub-str
[ clap::parse::validator] Validator::gather_conflicts
[ clap::parse::validator] Validator::gather_conflicts:iter: id=global-flag
[ clap::parse::validator] groups_for_arg: name=global-flag
[ clap::parse::validator] Validator::gather_conflicts:iter: id=global-str
[ clap::parse::validator] groups_for_arg: name=global-str
[ clap::parse::validator] Validator::gather_conflicts:iter: id=sub-flag
[ clap::parse::validator] groups_for_arg: name=sub-flag
[ clap::parse::validator] Validator::gather_conflicts:iter: id=sub-str
[ clap::parse::validator] groups_for_arg: name=sub-str
[ clap::parse::validator] Validator::validate_required: required=ChildGraph([])
[ clap::parse::validator] Validator::gather_requirements
[ clap::parse::validator] Validator::gather_requirements:iter:global-flag
[ clap::parse::validator] Validator::gather_requirements:iter:global-str
[ clap::parse::validator] Validator::gather_requirements:iter:sub-flag
[ clap::parse::validator] Validator::gather_requirements:iter:sub-str
[ clap::parse::validator] Validator::validate_required_unless
[ clap::parse::validator] Validator::validate_matched_args
[ clap::parse::validator] Validator::validate_matched_args:iter:global-flag: vals=[]
[ clap::parse::validator] Validator::validate_arg_num_vals
[ clap::parse::validator] Validator::validate_arg_values: arg="global-flag"
[ clap::parse::validator] Validator::validate_arg_requires:"global-flag"
[ clap::parse::validator] Validator::validate_arg_num_occurs: "global-flag"=1
[ clap::parse::validator] Validator::validate_matched_args:iter:global-str: vals=[
"hello",
]
[ clap::parse::validator] Validator::validate_arg_num_vals
[ clap::parse::validator] Validator::validate_arg_values: arg="global-str"
[ clap::parse::validator] Validator::validate_arg_values: checking validator...
[ clap::parse::validator] good
[ clap::parse::validator] Validator::validate_arg_requires:"global-str"
[ clap::parse::validator] Validator::validate_arg_num_occurs: "global-str"=1
[ clap::parse::validator] Validator::validate_matched_args:iter:sub-flag: vals=[]
[ clap::parse::validator] Validator::validate_arg_num_vals
[ clap::parse::validator] Validator::validate_arg_values: arg="sub-flag"
[ clap::parse::validator] Validator::validate_arg_requires:"sub-flag"
[ clap::parse::validator] Validator::validate_arg_num_occurs: "sub-flag"=1
[ clap::parse::validator] Validator::validate_matched_args:iter:sub-str: vals=[
"world",
]
[ clap::parse::validator] Validator::validate_arg_num_vals
[ clap::parse::validator] Validator::validate_arg_values: arg="sub-str"
[ clap::parse::validator] Validator::validate_arg_values: checking validator...
[ clap::parse::validator] good
[ clap::parse::validator] Validator::validate_arg_requires:"sub-str"
[ clap::parse::validator] Validator::validate_arg_num_occurs: "sub-str"=1
[ clap::parse::parser] Parser::remove_overrides
[ clap::parse::validator] Validator::validate
[ clap::parse::parser] Parser::add_defaults
[ clap::parse::parser] Parser::add_defaults:iter:sub-str:
[ clap::parse::parser] Parser::add_value: doesn't have conditional defaults
[ clap::parse::parser] Parser::add_value:iter:sub-str: doesn't have default vals
[ clap::parse::parser] Parser::add_defaults:iter:global-str:
[ clap::parse::parser] Parser::add_value: doesn't have conditional defaults
[ clap::parse::parser] Parser::add_value:iter:global-str: doesn't have default vals
[ clap::parse::validator] Validator::validate_conflicts
[ clap::parse::validator] Validator::validate_exclusive
[ clap::parse::validator] Validator::gather_conflicts
[ clap::parse::validator] Validator::validate_required: required=ChildGraph([])
[ clap::parse::validator] Validator::gather_requirements
[ clap::parse::validator] Validator::validate_required_unless
[ clap::parse::validator] Validator::validate_matched_args
[ clap::parse::parser] Parser::remove_overrides
[ clap::parse::validator] Validator::validate
[ clap::parse::parser] Parser::add_defaults
[ clap::parse::parser] Parser::add_defaults:iter:global-str:
[ clap::parse::parser] Parser::add_value: doesn't have conditional defaults
[ clap::parse::parser] Parser::add_value:iter:global-str: doesn't have default vals
[ clap::parse::validator] Validator::validate_conflicts
[ clap::parse::validator] Validator::validate_exclusive
[ clap::parse::validator] Validator::gather_conflicts
[ clap::parse::validator] Validator::validate_required: required=ChildGraph([])
[ clap::parse::validator] Validator::gather_requirements
[ clap::parse::validator] Validator::validate_required_unless
[ clap::parse::validator] Validator::validate_matched_args
[ clap::parse::arg_matcher] ArgMatcher::get_global_values: global_arg_vec=[global-flag, global-str]
Opts { global_flag: true, global_str: Some("hello"), subcommand: Test(TestSubCommand { sub_flag: false, sub_str: None, subcommand: Test(TestSubSubCommand) }) }
Duplicate of https://github.com/clap-rs/clap/issues/1385
To elaborate a bit: the args do propagate and register, but you can't _access_ the args from anywhere except the place of definition. I'll be working on fixing it.
To elaborate a bit: the args do propagate and register, but you can't _access_ the args from anywhere except the place of definition. I'll be working on fixing it.
What do you mean? The arguments are not available from anywhere here, as you can see in the Debug output. Even if I try to read the arguments directly from the Opts itself and not from its sub-command objects, arguments show the wrong values.
Um... Your output was:
Opts { global_flag: true, global_str: Some("hello")...
It does work.
But then:
...: Test(TestSubCommand { sub_flag: false, sub_str: None, subcommand: Test(TestSubSubCommand) }) }
Unless I'm not understanding how Clap is supposed to behave, as I supplied --subflag --sub-str "world" the "sub_flag" and "sub_str" fields are not set properly.
Oh right, this is a separate bug. It's not even derive-specific:
use clap::{App, Arg};
fn main() {
let m = App::new("opts")
.arg(Arg::from("--global-flag").global(true))
.arg(Arg::from("--global-str <str>").required(false).global(true))
.subcommand(
App::new("test")
.arg(Arg::from("--sub-flag").global(true))
.arg(Arg::from("--sub-str <str>").required(false).global(true))
.subcommand(App::new("test"))
)
.get_matches_from(&[
"app",
"test",
"test",
"--global-flag",
"--global-str",
"hello",
"--sub-flag",
"--sub-str",
"world"
]);
println!("{:#?}", m);
}
ArgMatches {
args: {
global-flag: MatchedArg {
occurs: 1,
ty: CommandLine,
indices: [
1,
],
vals: [],
},
global-str: MatchedArg {
occurs: 1,
ty: CommandLine,
indices: [
3,
],
vals: [
"hello",
],
},
},
subcommand: Some(
SubCommand {
id: test,
name: "test",
matches: ArgMatches {
args: {
global-flag: MatchedArg {
occurs: 1,
ty: CommandLine,
indices: [
1,
],
vals: [],
},
global-str: MatchedArg {
occurs: 1,
ty: CommandLine,
indices: [
3,
],
vals: [
"hello",
],
},
},
subcommand: Some(
SubCommand {
id: test,
name: "test",
matches: ArgMatches {
args: {
global-flag: MatchedArg {
occurs: 1,
ty: CommandLine,
indices: [
1,
],
vals: [],
},
global-str: MatchedArg {
occurs: 1,
ty: CommandLine,
indices: [
3,
],
vals: [
"hello",
],
},
sub-flag: MatchedArg {
occurs: 1,
ty: CommandLine,
indices: [
4,
],
vals: [],
},
sub-str: MatchedArg {
occurs: 1,
ty: CommandLine,
indices: [
6,
],
vals: [
"world",
],
},
},
subcommand: None,
},
},
),
},
},
),
}
Indeed, sorry if I wasn't clear about the problem.
And I'm surprised no one encoutered this bug before, this seems like a not-very-common but still plausible scenario for a big CLI-based application.
Hi, are there any news on this?
If I can help with anything, just let me know! I don't know clap's codebase but I can dig into the code if no one has time to look into this problem ;)
@ClementNerma I would appreciate if you can. You can write a simple test and start digging using the debug logs.
I won't have much time to dig in the codebase in the following days, but I'll put my progress here:
https://github.com/ClementNerma/clap/tree/test-args-subcommands-conflicts
I've redacted a little "proof-of-concept" test in:
Most helpful comment
Indeed, sorry if I wasn't clear about the problem.
And I'm surprised no one encoutered this bug before, this seems like a not-very-common but still plausible scenario for a big CLI-based application.