clap-rs / clap

A full featured, fast Command Line Argument Parser for Rust
docs.rs/clap
Apache License 2.0
13.66k stars 1.02k forks source link

clap_derive parsing of PathBuf with default_value of empty string still requires it to be specified on command line #5368

Closed akanalytics closed 4 months ago

akanalytics commented 4 months ago

Please complete the following tasks

Rust Version

rustc 1.75.0 (82e1608df 2023-12-21)

Clap Version

4.5.1

Minimal reproducible code

fn main() {
#[derive(Debug, clap::Parser)]
struct MyStruct {
    #[arg(short, long, default_value="")]
    path: PathBuf,
}

let cli = clap::Parser::parse_from(args());
println!("{cli:#?}");

Steps to reproduce the bug with the above code

cargo run

Actual Behaviour

Despite a default_value being specified, it is still required on the comamnd line error: a value is required for '--path ' but none was supplied An empty PathBuf is a valid PathBuf and should be allowed as a default.

Expected Behaviour

When path is not specified on the command line I expect PathBuf to default to "" (the empty pathbuf)

Additional Context

Deafulting to "somefile" etc all works as expected - just empty string fails

Debug Output

[clap_builder::builder::debug_asserts]Command::_debug_asserts [clap_builder::builder::debug_asserts]Arg::_debug_asserts:path [clap_builder::builder::debug_asserts]Arg::_debug_asserts:help [clap_builder::builder::debug_asserts]Command::_verify_positionals [clap_builder::parser::parser]Parser::get_matches_with [clap_builder::parser::parser]Parser::add_defaults [clap_builder::parser::parser]Parser::add_defaults:iter:path: [clap_builder::parser::parser]Parser::add_default_value: doesn't have conditional defaults [clap_builder::parser::parser]Parser::add_default_value:iter:path: has default vals [clap_builder::parser::parser]Parser::add_default_value:iter:path: wasn't used [clap_builder::parser::parser]Parser::react action=Set, identifier=None, source=DefaultValue [clap_builder::parser::arg_matcher]ArgMatcher::start_custom_arg: id="path", source=DefaultValue [clap_builder::parser::parser]Parser::push_arg_values: [""] [clap_builder::parser::parser]Parser::add_single_val_to_arg: cur_idx:=1 [clap_builder::builder::command]Command::color: Color setting... [clap_builder::builder::command]Auto [clap_builder::builder::command]Command::color: Color setting... [clap_builder::builder::command]Auto error: a value is required for '--path ' but none was supplied

akanalytics commented 4 months ago

Sorry - this is a duplicate of #4746. But I think this is still a bug, that seems to trip people up. Paths are such a common command line parameter.

Usecase: lots of code can use an empty pathbuf as an alternative to Option. Rust explicitly offers a new() constructor which does exactly this, and it reduces the boilerplate in many places.

Using "." does not have the same meaning. (ls . and ls '' give different results on my linux system).

Although personally Im not a fan of empty PathBufs, Rust clearly does support them, and command line tools such as the Linux 'ls' command does distinguish between empty paths and "." paths.

epage commented 4 months ago

Let's move the conversation to #4746 to keep it all in one place