Skip to content

Commit

Permalink
Merge pull request #4180 from epage/specialized
Browse files Browse the repository at this point in the history
fix(derive): Replace clap attributes with command, arg, and value
  • Loading branch information
epage committed Sep 2, 2022
2 parents 20ba828 + 47e3cb6 commit f513862
Show file tree
Hide file tree
Showing 117 changed files with 697 additions and 656 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -66,6 +66,7 @@ Deprecated
- `Arg::number_of_values` in favor of `Arg::num_args`
- `default_value_os`, `default_values_os`, `default_value_if_os`, and `default_value_ifs_os` as the non `_os` variants now accept either a `str` or an `OsStr`
- `Command::dont_collapse_args_in_usage` is now the default and is deprecated
- *(derive)* `structopt` and `clap` attributes in favor of the more specific `command`, `arg`, and `value`

### Features

Expand Down
30 changes: 15 additions & 15 deletions clap_complete/examples/completion-derive.rs
Expand Up @@ -19,41 +19,41 @@ use std::io;
use std::path::PathBuf;

#[derive(Parser, Debug, PartialEq)]
#[clap(
#[command(
name = "value_hints_derive",
// Command::trailing_var_ar is required to use ValueHint::CommandWithArguments
trailing_var_arg = true,
)]
struct Opt {
/// If provided, outputs the completion file for given shell
#[clap(long = "generate", value_enum)]
#[arg(long = "generate", value_enum)]
generator: Option<Shell>,
// Showcasing all possible ValueHints:
#[clap(long, value_hint = ValueHint::Unknown)]
#[arg(long, value_hint = ValueHint::Unknown)]
unknown: Option<String>,
#[clap(long, value_hint = ValueHint::Other)]
#[arg(long, value_hint = ValueHint::Other)]
other: Option<String>,
#[clap(short, long, value_hint = ValueHint::AnyPath)]
#[arg(short, long, value_hint = ValueHint::AnyPath)]
path: Option<PathBuf>,
#[clap(short, long, value_hint = ValueHint::FilePath)]
#[arg(short, long, value_hint = ValueHint::FilePath)]
file: Option<PathBuf>,
#[clap(short, long, value_hint = ValueHint::DirPath)]
#[arg(short, long, value_hint = ValueHint::DirPath)]
dir: Option<PathBuf>,
#[clap(short, long, value_hint = ValueHint::ExecutablePath)]
#[arg(short, long, value_hint = ValueHint::ExecutablePath)]
exe: Option<PathBuf>,
#[clap(long, value_hint = ValueHint::CommandName)]
#[arg(long, value_hint = ValueHint::CommandName)]
cmd_name: Option<OsString>,
#[clap(short, long, value_hint = ValueHint::CommandString)]
#[arg(short, long, value_hint = ValueHint::CommandString)]
cmd: Option<String>,
#[clap(value_hint = ValueHint::CommandWithArguments)]
#[arg(value_hint = ValueHint::CommandWithArguments)]
command_with_args: Vec<String>,
#[clap(short, long, value_hint = ValueHint::Username)]
#[arg(short, long, value_hint = ValueHint::Username)]
user: Option<String>,
#[clap(short, long, value_hint = ValueHint::Hostname)]
#[arg(short, long, value_hint = ValueHint::Hostname)]
host: Option<String>,
#[clap(long, value_hint = ValueHint::Url)]
#[arg(long, value_hint = ValueHint::Url)]
url: Option<String>,
#[clap(long, value_hint = ValueHint::EmailAddress)]
#[arg(long, value_hint = ValueHint::EmailAddress)]
email: Option<String>,
}

Expand Down
18 changes: 9 additions & 9 deletions clap_complete/src/dynamic.rs
Expand Up @@ -8,7 +8,7 @@ pub mod bash {
use unicode_xid::UnicodeXID;

#[derive(clap::Subcommand)]
#[clap(hide = true)]
#[command(hide = true)]
#[allow(missing_docs)]
#[derive(Clone, Debug)]
pub enum CompleteCommand {
Expand All @@ -17,15 +17,15 @@ pub mod bash {
}

#[derive(clap::Args)]
#[clap(group = clap::ArgGroup::new("complete").multiple(true).conflicts_with("register"))]
#[command(group = clap::ArgGroup::new("complete").multiple(true).conflicts_with("register"))]
#[allow(missing_docs)]
#[derive(Clone, Debug)]
pub struct CompleteArgs {
/// Path to write completion-registration to
#[clap(long, required = true)]
#[arg(long, required = true)]
register: Option<std::path::PathBuf>,

#[clap(
#[arg(
long,
required = true,
value_name = "COMP_CWORD",
Expand All @@ -34,29 +34,29 @@ pub mod bash {
)]
index: Option<usize>,

#[clap(long, hide_short_help = true, group = "complete")]
#[arg(long, hide_short_help = true, group = "complete")]
ifs: Option<String>,

#[clap(
#[arg(
long = "type",
required = true,
hide_short_help = true,
group = "complete"
)]
comp_type: Option<CompType>,

#[clap(long, hide_short_help = true, group = "complete")]
#[arg(long, hide_short_help = true, group = "complete")]
space: bool,

#[clap(
#[arg(
long,
conflicts_with = "space",
hide_short_help = true,
group = "complete"
)]
no_space: bool,

#[clap(raw = true, hide_short_help = true, group = "complete")]
#[arg(raw = true, hide_short_help = true, group = "complete")]
comp_words: Vec<OsString>,
}

Expand Down
12 changes: 12 additions & 0 deletions clap_derive/src/attr.rs
Expand Up @@ -32,6 +32,12 @@ impl ClapAttr {
Some(Sp::new(AttrKind::Clap, attr.path.span()))
} else if attr.path.is_ident("structopt") {
Some(Sp::new(AttrKind::StructOpt, attr.path.span()))
} else if attr.path.is_ident("command") {
Some(Sp::new(AttrKind::Command, attr.path.span()))
} else if attr.path.is_ident("arg") {
Some(Sp::new(AttrKind::Arg, attr.path.span()))
} else if attr.path.is_ident("value") {
Some(Sp::new(AttrKind::Value, attr.path.span()))
} else {
None
};
Expand Down Expand Up @@ -194,13 +200,19 @@ impl ToTokens for AttrValue {
pub enum AttrKind {
Clap,
StructOpt,
Command,
Arg,
Value,
}

impl AttrKind {
pub fn as_str(&self) -> &'static str {
match self {
Self::Clap => "clap",
Self::StructOpt => "structopt",
Self::Command => "command",
Self::Arg => "arg",
Self::Value => "value",
}
}
}
6 changes: 3 additions & 3 deletions clap_derive/src/derives/args.rs
Expand Up @@ -204,7 +204,7 @@ pub fn gen_augment(
Kind::Command(_)
| Kind::Value(_)
| Kind::Subcommand(_)
| Kind::Skip(_)
| Kind::Skip(_, _)
| Kind::FromGlobal(_)
| Kind::ExternalSubcommand => None,
Kind::Flatten => {
Expand Down Expand Up @@ -384,7 +384,7 @@ pub fn gen_constructor(fields: &[(&Field, Item)]) -> TokenStream {
#field_name: clap::FromArgMatches::from_arg_matches_mut(#arg_matches)?
},

Kind::Skip(val) => match val {
Kind::Skip(val, _) => match val {
None => quote_spanned!(kind.span()=> #field_name: Default::default()),
Some(val) => quote_spanned!(kind.span()=> #field_name: (#val).into()),
},
Expand Down Expand Up @@ -463,7 +463,7 @@ pub fn gen_updater(fields: &[(&Field, Item)], use_self: bool) -> TokenStream {
}
},

Kind::Skip(_) => quote!(),
Kind::Skip(_, _) => quote!(),

Kind::Arg(ty) | Kind::FromGlobal(ty) => gen_parsers(item, ty, field_name, field, Some(&access)),
}
Expand Down
2 changes: 1 addition & 1 deletion clap_derive/src/derives/subcommand.rs
Expand Up @@ -137,7 +137,7 @@ fn gen_augment(
let kind = item.kind();

match &*kind {
Kind::Skip(_) => None,
Kind::Skip(_, _) => None,

Kind::ExternalSubcommand => {
let ty = match variant.fields {
Expand Down
2 changes: 1 addition & 1 deletion clap_derive/src/derives/value_enum.rs
Expand Up @@ -78,7 +78,7 @@ fn lits(variants: &[(&Variant, Item)]) -> Vec<(TokenStream, Ident)> {
variants
.iter()
.filter_map(|(variant, item)| {
if let Kind::Skip(_) = &*item.kind() {
if let Kind::Skip(_, _) = &*item.kind() {
None
} else {
if !matches!(variant.fields, Fields::Unit) {
Expand Down
70 changes: 49 additions & 21 deletions clap_derive/src/item.rs
Expand Up @@ -197,7 +197,7 @@ impl Item {

Kind::ExternalSubcommand
| Kind::FromGlobal(_)
| Kind::Skip(_)
| Kind::Skip(_, _)
| Kind::Command(_)
| Kind::Value(_)
| Kind::Arg(_) => (),
Expand Down Expand Up @@ -321,7 +321,7 @@ impl Item {

res.kind = Sp::new(Kind::Subcommand(ty), res.kind.span());
}
Kind::Skip(_) => {
Kind::Skip(_, _) => {
if res.has_explicit_methods() {
abort!(
res.kind.span(),
Expand Down Expand Up @@ -463,7 +463,10 @@ impl Item {
}
Some(MagicAttrName::Skip) => {
let expr = attr.value.clone();
let kind = Sp::new(Kind::Skip(expr), attr.name.clone().span());
let kind = Sp::new(
Kind::Skip(expr, self.kind.attr_kind()),
attr.name.clone().span(),
);
Some(kind)
}
_ => None,
Expand All @@ -475,16 +478,28 @@ impl Item {
}

for attr in &parsed {
match attr.kind.get() {
AttrKind::Clap => {}
AttrKind::StructOpt => {
let actual_attr_kind = *attr.kind.get();
let expected_attr_kind = self.kind.attr_kind();
match (actual_attr_kind, expected_attr_kind) {
(AttrKind::Clap, _) | (AttrKind::StructOpt, _) => {
self.deprecations.push(Deprecation::attribute(
"4.0.0",
*attr.kind.get(),
AttrKind::Clap,
actual_attr_kind,
expected_attr_kind,
attr.kind.span(),
));
}

_ if attr.kind != expected_attr_kind => {
abort!(
attr.kind.span(),
"Expected `{}` attribute instead of `{}`",
expected_attr_kind.as_str(),
actual_attr_kind.as_str()
);
}

_ => {}
}

if let Some(AttrValue::Call(tokens)) = &attr.value {
Expand All @@ -511,7 +526,7 @@ impl Item {
span: attr.name.span(),
id: "bare_value_parser",
version: "4.0.0",
description: "`#[clap(value_parser)]` is now the default and is no longer needed`".to_owned(),
description: "`#[arg(value_parser)]` is now the default and is no longer needed`".to_owned(),
});
self.value_parser = Some(ValueParser::Implicit(attr.name.clone()));
}
Expand All @@ -522,7 +537,7 @@ impl Item {
span: attr.name.span(),
id: "bare_action",
version: "4.0.0",
description: "`#[clap(action)]` is now the default and is no longer needed`".to_owned(),
description: "`#[arg(action)]` is now the default and is no longer needed`".to_owned(),
});
self.action = Some(Action::Implicit(attr.name.clone()));
}
Expand Down Expand Up @@ -568,7 +583,7 @@ impl Item {
} else {
abort!(
attr.name.clone(),
"#[clap(default_value_t)] (without an argument) can be used \
"#[arg(default_value_t)] (without an argument) can be used \
only on field level";

note = "see \
Expand Down Expand Up @@ -610,7 +625,7 @@ impl Item {
} else {
abort!(
attr.name.clone(),
"#[clap(default_values_t)] (without an argument) can be used \
"#[arg(default_values_t)] (without an argument) can be used \
only on field level";

note = "see \
Expand All @@ -622,7 +637,7 @@ impl Item {
if *container_type != Ty::Vec {
abort!(
attr.name.clone(),
"#[clap(default_values_t)] can be used only on Vec types";
"#[arg(default_values_t)] can be used only on Vec types";

note = "see \
https://github.com/clap-rs/clap/blob/master/examples/derive_ref/README.md#magic-attributes")
Expand Down Expand Up @@ -679,7 +694,7 @@ impl Item {
} else {
abort!(
attr.name.clone(),
"#[clap(default_value_os_t)] (without an argument) can be used \
"#[arg(default_value_os_t)] (without an argument) can be used \
only on field level";

note = "see \
Expand Down Expand Up @@ -721,7 +736,7 @@ impl Item {
} else {
abort!(
attr.name.clone(),
"#[clap(default_values_os_t)] (without an argument) can be used \
"#[arg(default_values_os_t)] (without an argument) can be used \
only on field level";

note = "see \
Expand All @@ -733,7 +748,7 @@ impl Item {
if *container_type != Ty::Vec {
abort!(
attr.name.clone(),
"#[clap(default_values_os_t)] can be used only on Vec types";
"#[arg(default_values_os_t)] can be used only on Vec types";

note = "see \
https://github.com/clap-rs/clap/blob/master/examples/derive_ref/README.md#magic-attributes")
Expand Down Expand Up @@ -868,12 +883,12 @@ impl Item {
(Kind::Arg(_), Kind::FromGlobal(_))
| (Kind::Arg(_), Kind::Subcommand(_))
| (Kind::Arg(_), Kind::Flatten)
| (Kind::Arg(_), Kind::Skip(_))
| (Kind::Arg(_), Kind::Skip(_, _))
| (Kind::Command(_), Kind::Subcommand(_))
| (Kind::Command(_), Kind::Flatten)
| (Kind::Command(_), Kind::Skip(_))
| (Kind::Command(_), Kind::Skip(_, _))
| (Kind::Command(_), Kind::ExternalSubcommand)
| (Kind::Value(_), Kind::Skip(_)) => {
| (Kind::Value(_), Kind::Skip(_, _)) => {
self.kind = kind;
}

Expand Down Expand Up @@ -1117,7 +1132,7 @@ pub enum Kind {
FromGlobal(Sp<Ty>),
Subcommand(Sp<Ty>),
Flatten,
Skip(Option<AttrValue>),
Skip(Option<AttrValue>, AttrKind),
ExternalSubcommand,
}

Expand All @@ -1130,10 +1145,23 @@ impl Kind {
Self::FromGlobal(_) => "from_global",
Self::Subcommand(_) => "subcommand",
Self::Flatten => "flatten",
Self::Skip(_) => "skip",
Self::Skip(_, _) => "skip",
Self::ExternalSubcommand => "external_subcommand",
}
}

pub fn attr_kind(&self) -> AttrKind {
match self {
Self::Arg(_) => AttrKind::Arg,
Self::Command(_) => AttrKind::Command,
Self::Value(_) => AttrKind::Value,
Self::FromGlobal(_) => AttrKind::Arg,
Self::Subcommand(_) => AttrKind::Command,
Self::Flatten => AttrKind::Command,
Self::Skip(_, kind) => *kind,
Self::ExternalSubcommand => AttrKind::Command,
}
}
}

#[derive(Clone)]
Expand Down

0 comments on commit f513862

Please sign in to comment.