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

fix: Misc fixes found when optimizing code size #4222

Merged
merged 8 commits into from Sep 16, 2022
2 changes: 2 additions & 0 deletions CHANGELOG.md
Expand Up @@ -229,6 +229,7 @@ Easier to catch changes:
- `#[clap(value_parser)]` and `#[clap(action)]` are now redundant
- *(derive)* `subcommand_required(true).arg_required_else_help(true)` is set instead of `SubcommandRequiredElseHelp` to give more meaningful errors when subcommands are missing and to reduce redundancy (#3280)
- *(derive)* Remove `arg_enum` attribute in favor of `value_enum` to match the new name (we didn't have support in v3 to mark it deprecated) (#4127)
- *(derive)* `next_help_heading` can now leak out of a `#[clap(flatten)]`, like all other command settings
- *(parser)* Assert when the CLI looksup an unknown args when external subcommand support is enabled to help catch bugs (#3703)
- *(assert)* Sometimes `Arg::default_missing_value` didn't require `num_args(0..=N)`, now it does (#4023)
- *(assert)* Leading dashes in `Arg::long` are no longer allowed (#3691)
Expand All @@ -238,6 +239,7 @@ Easier to catch changes:
- *(assert)* Ensure `overrides_with` IDs are valid
- *(assert)* Ensure no self-`overrides_with` now that Actions replace it
- *(assert)* Ensure subcommand names are not duplicated
- *(assert)* Assert on `mut_arg` receiving an invalid arg ID or `mut_subcommand` receiving an invalid command name

### Compatibility

Expand Down
5 changes: 0 additions & 5 deletions clap_derive/src/derives/args.rs
Expand Up @@ -194,26 +194,21 @@ pub fn gen_augment(
}
Kind::Flatten => {
let ty = &field.ty;
let old_heading_var = format_ident!("__clap_old_heading");
let next_help_heading = item.next_help_heading();
let next_display_order = item.next_display_order();
if override_required {
Some(quote_spanned! { kind.span()=>
let #old_heading_var = #app_var.get_next_help_heading().map(|s| clap::builder::Str::from(s.to_owned()));
let #app_var = #app_var
#next_help_heading
#next_display_order;
let #app_var = <#ty as clap::Args>::augment_args_for_update(#app_var);
let #app_var = #app_var.next_help_heading(clap::builder::Resettable::from(#old_heading_var));
})
} else {
Some(quote_spanned! { kind.span()=>
let #old_heading_var = #app_var.get_next_help_heading().map(|s| clap::builder::Str::from(s.to_owned()));
let #app_var = #app_var
#next_help_heading
#next_display_order;
let #app_var = <#ty as clap::Args>::augment_args(#app_var);
let #app_var = #app_var.next_help_heading(clap::builder::Resettable::from(#old_heading_var));
})
}
}
Expand Down
13 changes: 4 additions & 9 deletions clap_derive/src/derives/parser.rs
Expand Up @@ -29,6 +29,7 @@ use crate::item::Name;

pub fn derive_parser(input: &DeriveInput) -> TokenStream {
let ident = &input.ident;
let pkg_name = std::env::var("CARGO_PKG_NAME").ok().unwrap_or_default();

match input.data {
Data::Struct(DataStruct {
Expand All @@ -37,9 +38,7 @@ pub fn derive_parser(input: &DeriveInput) -> TokenStream {
}) => {
dummies::parser_struct(ident);

let name = Name::Assigned(quote!(std::env::var("CARGO_PKG_NAME")
.ok()
.unwrap_or_default()));
let name = Name::Assigned(quote!(#pkg_name));
let item = Item::from_args_struct(input, name);
let fields = fields
.named
Expand All @@ -57,9 +56,7 @@ pub fn derive_parser(input: &DeriveInput) -> TokenStream {
}) => {
dummies::parser_struct(ident);

let name = Name::Assigned(quote!(std::env::var("CARGO_PKG_NAME")
.ok()
.unwrap_or_default()));
let name = Name::Assigned(quote!(#pkg_name));
let item = Item::from_args_struct(input, name);
let fields = Punctuated::<Field, Comma>::new();
let fields = fields
Expand All @@ -74,9 +71,7 @@ pub fn derive_parser(input: &DeriveInput) -> TokenStream {
Data::Enum(ref e) => {
dummies::parser_enum(ident);

let name = Name::Assigned(quote!(std::env::var("CARGO_PKG_NAME")
.ok()
.unwrap_or_default()));
let name = Name::Assigned(quote!(#pkg_name));
let item = Item::from_subcommand_enum(input, name);
let variants = e
.variants
Expand Down
5 changes: 0 additions & 5 deletions clap_derive/src/derives/subcommand.rs
Expand Up @@ -181,28 +181,23 @@ fn gen_augment(
} else {
quote!()
};
let old_heading_var = format_ident!("__clap_old_heading");
let next_help_heading = item.next_help_heading();
let next_display_order = item.next_display_order();
let subcommand = if override_required {
quote! {
#deprecations
let #old_heading_var = #app_var.get_next_help_heading().map(|s| clap::builder::Str::from(s.to_owned()));
let #app_var = #app_var
#next_help_heading
#next_display_order;
let #app_var = <#ty as clap::Subcommand>::augment_subcommands_for_update(#app_var);
let #app_var = #app_var.next_help_heading(clap::builder::Resettable::from(#old_heading_var));
}
} else {
quote! {
#deprecations
let #old_heading_var = #app_var.get_next_help_heading().map(|s| clap::builder::Str::from(s.to_owned()));
let #app_var = #app_var
#next_help_heading
#next_display_order;
let #app_var = <#ty as clap::Subcommand>::augment_subcommands(#app_var);
let #app_var = #app_var.next_help_heading(clap::builder::Resettable::from(#old_heading_var));
}
};
Some(subcommand)
Expand Down
10 changes: 5 additions & 5 deletions examples/tutorial_builder/03_05_default_values.md
Expand Up @@ -2,19 +2,19 @@
$ 03_05_default_values --help
A simple to use, efficient, and full-featured Command Line Argument Parser

Usage: 03_05_default_values[EXE] [NAME]
Usage: 03_05_default_values[EXE] [PORT]

Arguments:
[NAME] [default: alice]
[PORT] [default: 2020]

Options:
-h, --help Print help information
-V, --version Print version information

$ 03_05_default_values
name: "alice"
port: 2020

$ 03_05_default_values bob
name: "bob"
$ 03_05_default_values 22
port: 22

```
12 changes: 8 additions & 4 deletions examples/tutorial_builder/03_05_default_values.rs
@@ -1,14 +1,18 @@
use clap::{arg, command};
use clap::{arg, command, value_parser};

fn main() {
let matches = command!() // requires `cargo` feature
.arg(arg!([NAME]).default_value("alice"))
.arg(
arg!([PORT])
.value_parser(value_parser!(u16))
.default_value("2020"),
)
.get_matches();

println!(
"name: {:?}",
"port: {:?}",
matches
.get_one::<String>("NAME")
.get_one::<u16>("PORT")
.expect("default ensures there is always a value")
);
}
10 changes: 5 additions & 5 deletions examples/tutorial_derive/03_05_default_values.md
Expand Up @@ -2,19 +2,19 @@
$ 03_05_default_values_derive --help
A simple to use, efficient, and full-featured Command Line Argument Parser

Usage: 03_05_default_values_derive[EXE] [NAME]
Usage: 03_05_default_values_derive[EXE] [PORT]

Arguments:
[NAME] [default: alice]
[PORT] [default: 2020]

Options:
-h, --help Print help information
-V, --version Print version information

$ 03_05_default_values_derive
name: "alice"
port: 2020

$ 03_05_default_values_derive bob
name: "bob"
$ 03_05_default_values_derive 22
port: 22

```
6 changes: 3 additions & 3 deletions examples/tutorial_derive/03_05_default_values.rs
Expand Up @@ -3,12 +3,12 @@ use clap::Parser;
#[derive(Parser)]
#[command(author, version, about, long_about = None)]
struct Cli {
#[arg(default_value_t = String::from("alice"))]
name: String,
#[arg(default_value_t = 2020)]
port: u16,
}

fn main() {
let cli = Cli::parse();

println!("name: {:?}", cli.name);
println!("port: {:?}", cli.port);
}
10 changes: 5 additions & 5 deletions src/builder/arg.rs
Expand Up @@ -146,7 +146,7 @@ impl Arg {
#[must_use]
pub fn short(mut self, s: impl IntoResettable<char>) -> Self {
if let Some(s) = s.into_resettable().into_option() {
assert!(s != '-', "short option name cannot be `-`");
debug_assert!(s != '-', "short option name cannot be `-`");
self.short = Some(s);
} else {
self.short = None;
Expand Down Expand Up @@ -241,7 +241,7 @@ impl Arg {
#[must_use]
pub fn short_alias(mut self, name: impl IntoResettable<char>) -> Self {
if let Some(name) = name.into_resettable().into_option() {
assert!(name != '-', "short alias name cannot be `-`");
debug_assert!(name != '-', "short alias name cannot be `-`");
self.short_aliases.push((name, false));
} else {
self.short_aliases.clear();
Expand Down Expand Up @@ -301,7 +301,7 @@ impl Arg {
#[must_use]
pub fn short_aliases(mut self, names: impl IntoIterator<Item = char>) -> Self {
for s in names {
assert!(s != '-', "short alias name cannot be `-`");
debug_assert!(s != '-', "short alias name cannot be `-`");
self.short_aliases.push((s, false));
}
self
Expand Down Expand Up @@ -357,7 +357,7 @@ impl Arg {
#[must_use]
pub fn visible_short_alias(mut self, name: impl IntoResettable<char>) -> Self {
if let Some(name) = name.into_resettable().into_option() {
assert!(name != '-', "short alias name cannot be `-`");
debug_assert!(name != '-', "short alias name cannot be `-`");
self.short_aliases.push((name, true));
} else {
self.short_aliases.clear();
Expand Down Expand Up @@ -412,7 +412,7 @@ impl Arg {
#[must_use]
pub fn visible_short_aliases(mut self, names: impl IntoIterator<Item = char>) -> Self {
for n in names {
assert!(n != '-', "short alias name cannot be `-`");
debug_assert!(n != '-', "short alias name cannot be `-`");
self.short_aliases.push((n, true));
}
self
Expand Down
41 changes: 21 additions & 20 deletions src/builder/command.rs
Expand Up @@ -195,10 +195,6 @@ impl Command {
/// [arguments]: Arg
#[must_use]
pub fn args(mut self, args: impl IntoIterator<Item = impl Into<Arg>>) -> Self {
let args = args.into_iter();
let (lower, _) = args.size_hint();
self.args.reserve(lower);

for arg in args {
self = self.arg(arg);
}
Expand All @@ -209,6 +205,10 @@ impl Command {
///
/// This can be useful for modifying the auto-generated help or version arguments.
///
/// # Panics
///
/// If the argument is undefined
///
/// # Examples
///
/// ```rust
Expand All @@ -231,15 +231,16 @@ impl Command {
/// assert!(res.is_ok());
/// ```
#[must_use]
pub fn mut_arg<F>(mut self, arg_id: impl Into<Id>, f: F) -> Self
#[cfg_attr(debug_assertions, track_caller)]
pub fn mut_arg<F>(mut self, arg_id: impl AsRef<str>, f: F) -> Self
where
F: FnOnce(Arg) -> Arg,
{
let id = arg_id.into();
let id = arg_id.as_ref();
let a = self
.args
.remove_by_name(id.as_str())
.unwrap_or_else(|| Arg::new(id));
.remove_by_name(id)
.unwrap_or_else(|| panic!("Argument `{}` is undefined", id));

self.args.push(f(a));
self
Expand All @@ -250,6 +251,10 @@ impl Command {
/// This can be useful for modifying auto-generated arguments of nested subcommands with
/// [`Command::mut_arg`].
///
/// # Panics
///
/// If the subcommand is undefined
///
/// # Examples
///
/// ```rust
Expand Down Expand Up @@ -279,7 +284,7 @@ impl Command {
let subcmd = if let Some(idx) = pos {
self.subcommands.remove(idx)
} else {
Self::new(Str::from(name.to_owned()))
panic!("Command `{}` is undefined", name)
};

self.subcommands.push(f(subcmd));
Expand Down Expand Up @@ -407,10 +412,6 @@ impl Command {
/// [`IntoIterator`]: std::iter::IntoIterator
#[must_use]
pub fn subcommands(mut self, subcmds: impl IntoIterator<Item = impl Into<Self>>) -> Self {
let subcmds = subcmds.into_iter();
let (lower, _) = subcmds.size_hint();
self.subcommands.reserve(lower);

for subcmd in subcmds {
self = self.subcommand(subcmd);
}
Expand Down Expand Up @@ -2219,7 +2220,7 @@ impl Command {
#[must_use]
pub fn short_flag_alias(mut self, name: impl IntoResettable<char>) -> Self {
if let Some(name) = name.into_resettable().into_option() {
assert!(name != '-', "short alias name cannot be `-`");
debug_assert!(name != '-', "short alias name cannot be `-`");
self.short_flag_aliases.push((name, false));
} else {
self.short_flag_aliases.clear();
Expand Down Expand Up @@ -2310,7 +2311,7 @@ impl Command {
#[must_use]
pub fn short_flag_aliases(mut self, names: impl IntoIterator<Item = char>) -> Self {
for s in names {
assert!(s != '-', "short alias name cannot be `-`");
debug_assert!(s != '-', "short alias name cannot be `-`");
self.short_flag_aliases.push((s, false));
}
self
Expand Down Expand Up @@ -2402,7 +2403,7 @@ impl Command {
#[must_use]
pub fn visible_short_flag_alias(mut self, name: impl IntoResettable<char>) -> Self {
if let Some(name) = name.into_resettable().into_option() {
assert!(name != '-', "short alias name cannot be `-`");
debug_assert!(name != '-', "short alias name cannot be `-`");
self.short_flag_aliases.push((name, true));
} else {
self.short_flag_aliases.clear();
Expand Down Expand Up @@ -2491,7 +2492,7 @@ impl Command {
#[must_use]
pub fn visible_short_flag_aliases(mut self, names: impl IntoIterator<Item = char>) -> Self {
for s in names {
assert!(s != '-', "short alias name cannot be `-`");
debug_assert!(s != '-', "short alias name cannot be `-`");
self.short_flag_aliases.push((s, true));
}
self
Expand Down Expand Up @@ -4041,7 +4042,7 @@ impl Command {
.map(|arg| arg.get_id().clone())
.collect();

assert!(args_missing_help.is_empty(),
debug_assert!(args_missing_help.is_empty(),
"Command::help_expected is enabled for the Command {}, but at least one of its arguments does not have either `help` or `long_help` set. List of such arguments: {}",
self.name,
args_missing_help.join(", ")
Expand Down Expand Up @@ -4216,7 +4217,7 @@ impl Command {
}

fn _copy_subtree_for_help(&self) -> Command {
let mut cmd = Command::new(self.get_name().to_string())
let mut cmd = Command::new(self.name.clone())
.hide(self.is_hide_set())
.global_setting(AppSettings::DisableHelpFlag)
.global_setting(AppSettings::DisableVersionFlag)
Expand Down Expand Up @@ -4299,7 +4300,7 @@ impl Command {

#[inline]
pub(crate) fn contains_short(&self, s: char) -> bool {
assert!(
debug_assert!(
self.is_set(AppSettings::Built),
"If Command::_build hasn't been called, manually search through Arg shorts"
);
Expand Down
5 changes: 0 additions & 5 deletions src/mkeymap.rs
Expand Up @@ -90,11 +90,6 @@ impl MKeyMap {
self.keys.iter().any(|x| x.key == key)
}

/// Reserves capacity for at least additional more elements to be inserted
pub(crate) fn reserve(&mut self, additional: usize) {
self.args.reserve(additional);
}

/// Push an argument in the map.
pub(crate) fn push(&mut self, new_arg: Arg) {
self.args.push(new_arg);
Expand Down