clap-rs v3.0.0 Release Notes

Release Date: 2021-12-31 // over 2 years ago
  • Note: clap v3 has been in development for several years and has changed hands multiple times. Unfortunately, our changelog might be incomplete, whether in changes or their motivation.

    Highlights

    A special thanks to the maintainers, contributors, beta users, and sponsors who have helped along this journey, especially kbknapp.

    ๐Ÿ“„ StructOpt Integration

    ๐Ÿ“„ StructOpt provides a serde-like declarative ๐Ÿ‘€ approach to defining your parser. The main benefits we've seen so far from integrating are:

    • Tighter feedback between the design of clap and the derives
    • More universal traits. Crates exist for common CLI patterns (example) and we've re-designed the StructOpt traits so crates built on clap3 can be reused not just with other derives but also people using the builder API. People can even hand implement these so people using the builder API won't have the pay the cost for derives.

    Custom Help Headings

    Previously, clap automatically grouped arguments in the help as either ARGS, FLAGS, OPTIONS, and SUBCOMMANDS.

    0๏ธโƒฃ You can now override the default group with Arg::help_heading and App::subcommand_help_heading. To apply a heading to a series of arguments, you can set App::help_heading.

    ๐Ÿ—„ Deprecations

    ๐Ÿ—„ While a lot of deprecations have been added to clean up the API (overloaded meaning of Arg::multiple) or make things more consistent, some particular highlights are:

    Migrating

    From clap v2

    โœ… 1. Add CLI tests, -h and --help output at a minimum (recommendation: trycmd for snapshot testing) โšก๏ธ 2. Update your dependency 1. If you use no-default-features: add the std feature

    1. Resolve compiler errors
    2. Resolve behavior changes
      1. Refactor your App creation to a function and add a test similar to the one below, resolving any of its assertions
      2. Look over the "subtle changes" under BREAKING CHANGES
      3. If using builder: test your application under various circumstances to see if ArgMatches asserts regarding AllowInvalidUtf8.
    3. At your leisure: resolve deprecation notices

    โœ… Example test:

    fn app() -> clap::App<'static> {
        ...
    }
    
    #[test]
    fn verify_app() {
        app().debug_assert();
    }
    

    From structopt 0.3.25

    โœ… 1. Add CLI tests, -h and --help output at a minimum (recommendation: trycmd for snapshot testing)

    1. Replace your dependency from structopt = "..." to clap = { version = "3.0", features = ["derive"] }
      1. If you use no-default-features: add the std feature
    2. Resolve compiler errors, including
      1. Update your use statements from structopt and structopt::clap to clap
    3. Resolve behavior changes
      1. Add a test similar to the one below, resolving any of its assertions
      2. Look over the "subtle changes" under BREAKING CHANGES
    4. At your leisure: resolve deprecation notices

    โœ… Example test:

    #[derive(clap::StructOpt)]
    struct Args {
        ...
    }
    
    #[test]
    fn verify_app() {
        use clap::IntoApp;
        Args::into_app().debug_assert()
    }
    

    From clap v3.0.0-beta.5

    โœ… 1. Add CLI tests, -h and --help output at a minimum (recommendation: trycmd for snapshot testing) โšก๏ธ 2. Update your dependency 1. Add in derive, env, cargo, or unicode feature flags as needed

    1. Resolve compiler errors
      1. If you use yaml, clap_app!, or usage parser: revert any changes you made for clap3
      2. Change Arg::about Arg::long_about back to help and long_help and change PossibleValue::about to help (clap-rs/clap#3075)
      3. Change AppSettings::HelpRequired to AppSettings::HelpExpected
      4. Change PossibleValue::hidden to PossibleValue::hide
      5. Change App::subcommand_placeholder to App::subcommand_value_name / App::subcommand_help_heading
    2. Resolve behavior changes
      1. Add the above listed test appropriate for your application and resolve any problems it reports
      2. If using derive: see the structopt breaking changes section for Vec changes
      3. If using builder: test your application under various circumstances to see if ArgMatches asserts regarding AllowInvalidUtf8.
    3. At your leisure: resolve deprecation notices

    ๐Ÿ’ฅ BREAKING CHANGES

    From clap 2

    Subtle changes (i.e. compiler won't catch):

    • 0๏ธโƒฃ AppSettings::UnifiedHelpMessage is now default behaviour
      • {flags} and {unified} will assert if present in App::help_template
      • See clap-rs/clap#2807
    • 0๏ธโƒฃ AppSettings::EnableColoredHelp is now the default behavior but can be opted-out with AppSettings::DisableColoredHelp (clap-rs/clap#2806)
    • App::override_usage no longer implies a leading \t, allowing multi lined usages
    • Arg::require_equals no longer implies ArgSettings::ForbidEmptyValues (#2233)
    • Arg::require_delimiter no longer implies ArgSettings::TakesValue and ArgSettings::UseValueDelimiter (#2233)
    • Arg::env, Arg::env_os, Arg::last, Arg::require_equals, Arg::allow_hyphen_values, Arg::hide_possible_values, Arg::hide_default_value, Arg::hide_env_values, Arg::case_insensitive and Arg::multiple_values no longer imply ArgSettings::TakesValue (#2233)
    • ArgMatches::is_present no longer checks subcommand names
    • Some env variable values are now considered false for flags, not just "not-present" (clap-rs/clap#2539)
    • ๐Ÿ”„ Changed ...s meaning in usage parser. Before, it always meant multiple which is still true for --option [val].... Now [name]... --option [val] results in ArgSettings::MultipleOccurrences.
    • Usage exit code changed from 1 to 2 (clap-rs/clap#1327)
    • Reject --foo=bar when takes_value(false) (clap-rs/clap#1543)
    • No longer accept an arbitrary number of - for long arguments (-----long)

    Easier to catch changes:

    • 0๏ธโƒฃ When using no-default-features, you now have to specify the std feature (reserved for future work)
    • ๐Ÿ‘ Gated env support behind env feature flag
      • Impacts Arg::env, Arg::env_os, Arg::hide_env_values, ArgSettings::HideEnvValues
      • See clap-rs/clap#2694
    • Gated crate information behind cargo feature flag
      • Impacts crate_name!, crate_version!, crate_authors!, crate_description!, app_from_crate!
    • 0๏ธโƒฃ AppSettings::StrictUtf8 is now default behaviour and asserts if AppSettings::AllowInvalidUtf8ForExternalSubcommands and ArgSettings::AllowInvalidUtf8 and ArgMatches::value_of_os aren't used together
    • Arg::short and Arg::value_delimiter now take a char instead of a &str
    • ArgMatches panics on unknown arguments
    • โœ‚ Removed VersionlessSubcommands, making it the default (see clap-rs/clap#2812)
    • Completion generation has been split out into [clap_complete](./clap_complete).
    • โœ‚ Removed ArgSettings::EmptyValues in favor of ArgSettings::ForbidEmptyValues
    • Validator signatures have been loosed:
      • Arg::validator now takes first argument as Fn(&str) -> Result<O, E: ToString> instead of Fn(String) -> Result<(), String>
      • Arg::validator_os now takes first argument as Fn(&OsStr) -> Result<O, OsString> instead of Fn(&OsStr) -> Result<(), OsString>
    • ๐Ÿ‘€ Arg::value_name now sets, rather than appends (see clap-rs/clap#2634)
    • โฌ†๏ธ Upgrade yaml-rust from 0.3 to 0.4
    • Replaced ArgGroup::from(BTreeMap) to ArgGroup::from(yaml)
    • Replaced ArgMatches::usage with App::generate_usage
    • Replaced Arg::settings with Arg::setting(Setting1 | Setting2)
    • App and Arg now need only one lifetime
    • 0๏ธโƒฃ Removed deprecated App::with_defaults, replaced with app_from_crate
    • โœ‚ Removed deprecated AppSettings::PropagateGlobalValuesDown (now the default)
    • Some App functions, like App::write_help now take &mut self instead of &self
    • Error::message is now private, use Error::to_string
    • Arg::default_value_if, Arg::default_value_if_os, Arg::default_value_ifs, Arg::default_value_ifs_os now takes the default value parameter as an option (clap-rs/clap#1406)
    • ๐Ÿ–จ Changed App::print_help & App::print_long_help to now return std::io::Result
    • Changed App::write_help & App::write_long_help to now return std::io::Result
    • Changed Arg::index, Arg::number_of_values, Arg::min_values, Arg::max_values to taking usize instead of u64
    • ๐Ÿ”„ Changed Error::info to type Vec<String> instead of Option<Vec<String>>
    • ๐Ÿ”„ Changed ArgMatches::subcommand to now return Option<(&str, &ArgMatches)>
    • ๐Ÿ“‡ Renamed ErrorKind::MissingArgumentOrSubcommand to ErrorKind::DisplayHelpOnMissingArgumentOrSubcommand
    • ๐Ÿ“‡ Renamed ErrorKind::HelpDisplayed to ErrorKind::DisplayHelp
    • ๐Ÿ“‡ Renamed ErrorKind::VersionDisplayed to ErrorKind::DisplayVersion
    • โž• Added #[non_exhaustive] to clap::{ValueHint, ErrorKind, AppSettings, ArgSettings} (clap-rs/clap#3167)

    From structopt 0.3.25

    • 0๏ธโƒฃ By default, the App isn't initialized with crate information anymore. Now opt-in via #[clap(author)], #[clap(about)], #[clap(version)] (clap-rs/clap#3034)
    • 0๏ธโƒฃ #[clap(default_value)] is replaced with #[clap(default_value_t)] (clap-rs/clap#1694)
    • Subcommands nested under subcommands now needs a #[clap(subcommand)] attribute (clap-rs/clap#2587)
    • Vec<_> and Option<Vec<_>> have changed from multiple to multiple_occurrences

    On top of the clap 2 changes

    ๐ŸŽ Performance

    From clap 2

    • ๐Ÿ— Split out non-default unicode feature flag for faster builds and smaller binaries for ASCII-only CLIs.
    • ๐Ÿ— Split out non-default env feature flag for faster builds and smaller binaries.

    ๐Ÿ”‹ Features

    From clap 2

    • ๐Ÿ“œ Integration of structopt::StructOpt via clap::Parser (requires derive feature flag)
    • Custom help headings
      • App::help_heading (apply to all future args)
      • Arg::help_heading (apply to current arg)
      • App::subcommand_help_heading along with App::subcommand_value_name (apply to subcommands)
      • See clap-rs/clap#805
      • AppSettings::UnifiedHelpMessage is now default behaviour (clap-rs/clap#2807)
    • Deriving of ArgEnum for generating Arg::possible_values (requires derive feature flag)
    • Disable built-in help/version behavior with AppSettings::NoAutoHelp and AppSettings::NoAutoVersion
    • ๐Ÿ”„ Change an existing arg with new builder method mut_arg (particularly helpful for --help and --version)
    • Provide extra context in long help messages (--help) with before_long_help and after_long_help (clap-rs/clap#1903)
    • Detect missing help descriptions via debug asserts by enabling AppSettings::HelpExpected
    • Aliases for short flags (clap-rs/clap#1896)
    • Validate UTF-8 values, rather than panicing during ArgMatches::value_of thanks to AppSettings::AllowInvalidUtf8ForExternalSubcommands and ArgSettings::AllowInvalidUtf8
      • Debug builds will assert when the ArgMatches calls do not match the UTF-8 setting.
      • See clap-rs/clap#751
    • clap::PossibleValue to allow
    • ๐Ÿ‘ Allow arguments to conflict with all others via Arg::exclusive (clap-rs/clap#1583)
    • Validate arguments with a regex (required regex feature flag)
    • Arg::default_missing_value for cases like --color[=<WHEN>] (clap-rs/clap#1587)
    • clap::App::color / clap::ColorChoice to specify color setting for the app
    • Custom error reporting with App::error
    • โœ… App::debug_assert test helper
    • Replace Arg::multiple(bool) with Arg::multiple_values / Arg::multiple_occurrences
      • Positionals can be either
    • โž• Added support for flag subcommands like pacman (clap-rs/clap#1361)
    • ๐Ÿ“œ Partial parsing via AppSettings::IgnoreErrors (clap-rs/clap#1880)
    • ๐Ÿ–จ Enable cmd help to print long help (--help instead of -h) with AppSettings::UseLongFormatForHelpSubcommand (clap-rs/clap#2435)
    • ๐Ÿ‘ Allow long arg abbreviations like we do with subcommands via AppSettings::InferLongArgs (clap-rs/clap#2435)
    • Detect subcommands among positional arguments with AppSettings::SubcommandPrecedenceOverArg
    • Give completion scripts hints with Arg::value_hint (clap-rs/clap#1793)
    • ๐Ÿ‘ Allow unsetting defaults with
    • Arg::default_value_if, Arg::default_value_if_os, Arg::default_value_ifs, Arg::default_value_ifs_os (clap-rs/clap#1406)
    • Interpret some env variable values as false for flags, in addition to "not-present" (clap-rs/clap#2539)
      • n, no, f, false, off, 0
    • โž• Added arg! macro for creating an Arg from a compile-time usage parser

    • (Experimental) Busybox-like multi-call support

      • See AppSettings::Multicall behind unstable-multicall feature flag
      • See clap-rs/clap#1120
    • (Experimental) Alias an argument to anything group of arguments

      • See App::replace behind unstable-replace feature flag
      • See clap-rs#1603
    • (Experimental) Grouping of multiple values within multiple occurrences

      • See ArgMatches::grouped_values_of behind unstable-grouped feature flag
      • See clap-rs/clap#1026

    From structopt 0.3.25

    • Allow defaulting with native types via new default_value_t [= <expr>] attribute (clap-rs/clap#1694)
    • ๐Ÿ†• New update API
    • ๐Ÿ†• New arg_enum attribute for integrating with ArgEnum trait

    On top of the clap 2 changes

    ๐Ÿ›  Fixes

    From clap 2

    • ๐Ÿ Correctly handle colored output on Windows
    • Only generate version flags when App::version, App::long_version are set (see clap-rs/clap#2812)
    • General completion script improvements
    • 0๏ธโƒฃ Limited default help text wrapping to 100 when wrap_help feature is not enabled
    • Be more specific than Arg::multiple with Arg::multiple_values and Arg::multiple_occurrences
    • app_from_crate! defaults to separating multiple authors with ", "
    • Ensure all examples work
    • IgnoreCase is now unicode aware (requires unicode feature flag)
    • Always respect ColorChoice::Never, even if that means we skip colors in some cases
    • ArgMatches panics on unknown arguments
    • Gracefully handle empty authors field in Cargo.toml with app_from_crate
    • Do not show --help in cmd help with DisableHelpFlag (clap-rs/clap#3169)
    • Do not show --help in cmd help help that doesn't work (clap-rs/clap#3169)

    From structopt 0.3.25

    • ๐Ÿ‘Œ Support SubcommandsNegateReqs by allowing required Option<_>s (clap-rs/clap#2255)
    • ๐Ÿ“œ Infer AllowInvalidUtf8 based on parser (clap-rs/clap#751)
    • Gracefully handle empty authors field in Cargo.toml
    • Don't panic with default_value_os but treat it like default_value (clap-rs/clap#3031)
    • When using flatten and subcommand, ensure our doc comment always overrides the nested container's doc comment, whether it has only about or about and long_about ([clap-rs/clap#3175](]https://github.com/clap-rs/clap/pull/3175))

    On top of the clap 2 changes

    Minimum Required Rust

    • ๐Ÿš€ As of this release, clap requires rustc 1.54.0 or greater.