Skip to content

Commit 996d50a

Browse files
authored
Merge pull request #3228 from spinframework/clap-deprecated
cli: Resolve clap/deprecated warnings
2 parents 4887765 + bfc2e2c commit 996d50a

File tree

11 files changed

+65
-85
lines changed

11 files changed

+65
-85
lines changed

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ rust-version = "1.86"
1818
anyhow = { workspace = true }
1919
async-trait = { workspace = true }
2020
bytes = { workspace = true }
21-
clap = { workspace = true, features = ["derive", "env"] }
21+
# 'deprecated' enables deprecation warnings
22+
clap = { workspace = true, features = ["deprecated", "derive", "env"] }
2223
clearscreen = "4"
2324
comfy-table = "7"
2425
command-group = "2"

crates/runtime-factors/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ pub struct TriggerAppArgs {
9696
/// Set a key/value pair (key=value) in the application's
9797
/// default store. Any existing value will be overwritten.
9898
/// Can be used multiple times.
99-
#[clap(long = "key-value", parse(try_from_str = parse_kv))]
99+
#[clap(long = "key-value", value_parser = parse_kv)]
100100
pub key_values: Vec<(String, String)>,
101101

102102
/// Run a SQLite statement such as a migration against the default database.
@@ -116,7 +116,7 @@ pub struct TriggerAppArgs {
116116
///
117117
/// This option may be repeated. If the same key is specified multiple times
118118
/// the last value will be used.
119-
#[clap(long, multiple = true, value_parser = clap::value_parser!(VariableSource),
119+
#[clap(long, value_parser = clap::value_parser!(VariableSource),
120120
value_name = "KEY=VALUE | @FILE.json | @FILE.toml")]
121121
pub variable: Vec<VariableSource>,
122122

crates/trigger/src/cli.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ pub const SPIN_WORKING_DIR: &str = "SPIN_WORKING_DIR";
4141
/// A command that runs a TriggerExecutor.
4242
#[derive(Parser, Debug)]
4343
#[clap(
44-
usage = "spin [COMMAND] [OPTIONS]",
44+
override_usage = "spin [COMMAND] [OPTIONS]",
4545
next_help_heading = help_heading::<T, B::Factors>()
4646
)]
4747
pub struct FactorsTriggerCommand<T: Trigger<B::Factors>, B: RuntimeFactorsBuilder> {
@@ -89,7 +89,6 @@ pub struct FactorsTriggerCommand<T: Trigger<B::Factors>, B: RuntimeFactorsBuilde
8989
#[clap(
9090
name = FOLLOW_LOG_OPT,
9191
long = "follow",
92-
multiple_occurrences = true,
9392
)]
9493
pub follow_components: Vec<String>,
9594

src/clap_markdown/mod.rs

Lines changed: 30 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
//! the upstream crate because it is Clap 4 only. When we move to Clap 4
44
//! we should shift to using the original crate (and upstream changes such
55
//! as alphabetisation). See licences in this directory and NOTICES.md.
6-
//!
6+
//!
77
//! Autogenerate Markdown documentation for clap command-line tools
88
//!
99
//! See [**Examples**][Examples] for examples of the content `clap-markdown`
@@ -79,9 +79,7 @@ pub fn help_markdown<C: clap::CommandFactory>() -> String {
7979
}
8080

8181
/// Format the help information for `command` as Markdown, with custom options.
82-
pub fn help_markdown_custom<C: clap::CommandFactory>(
83-
options: &MarkdownOptions,
84-
) -> String {
82+
pub fn help_markdown_custom<C: clap::CommandFactory>(options: &MarkdownOptions) -> String {
8583
let command = C::command();
8684

8785
return help_markdown_command_custom(&command, options);
@@ -93,10 +91,7 @@ pub fn help_markdown_command(command: &clap::Command) -> String {
9391
}
9492

9593
/// Format the help information for `command` as Markdown, with custom options.
96-
pub fn help_markdown_command_custom(
97-
command: &clap::Command,
98-
options: &MarkdownOptions,
99-
) -> String {
94+
pub fn help_markdown_command_custom(command: &clap::Command, options: &MarkdownOptions) -> String {
10095
let mut buffer = String::with_capacity(100);
10196

10297
write_help_markdown(&mut buffer, &command, options);
@@ -121,11 +116,7 @@ pub fn print_help_markdown<C: clap::CommandFactory>() {
121116
println!("{}", buffer);
122117
}
123118

124-
fn write_help_markdown(
125-
buffer: &mut String,
126-
command: &clap::Command,
127-
options: &MarkdownOptions,
128-
) {
119+
fn write_help_markdown(buffer: &mut String, command: &clap::Command, options: &MarkdownOptions) {
129120
//----------------------------------
130121
// Write the document title
131122
//----------------------------------
@@ -142,7 +133,8 @@ fn write_help_markdown(
142133
buffer,
143134
"This document contains the help content for the `{}` command-line program.\n",
144135
title_name
145-
).unwrap();
136+
)
137+
.unwrap();
146138

147139
//----------------------------------
148140
// Write the table of contents
@@ -155,8 +147,7 @@ fn write_help_markdown(
155147
if options.show_table_of_contents {
156148
writeln!(buffer, "**Command Overview:**\n").unwrap();
157149

158-
build_table_of_contents_markdown(buffer, Vec::new(), command, 0)
159-
.unwrap();
150+
build_table_of_contents_markdown(buffer, Vec::new(), command, 0).unwrap();
160151

161152
write!(buffer, "\n").unwrap();
162153
}
@@ -171,13 +162,17 @@ fn write_help_markdown(
171162
// Write the footer
172163
//-----------------
173164
if options.show_footer {
174-
write!(buffer, r#"<hr/>
165+
write!(
166+
buffer,
167+
r#"<hr/>
175168
176169
<small><i>
177170
This document was generated automatically by
178171
<a href="https://crates.io/crates/clap-markdown"><code>clap-markdown</code></a>.
179172
</i></small>
180-
"#).unwrap();
173+
"#
174+
)
175+
.unwrap();
181176
}
182177
}
183178

@@ -215,12 +210,7 @@ fn build_table_of_contents_markdown(
215210
//----------------------------------
216211

217212
for subcommand in command.get_subcommands().sorted_by_key(|c| c.get_name()) {
218-
build_table_of_contents_markdown(
219-
buffer,
220-
command_path.clone(),
221-
subcommand,
222-
depth + 1,
223-
)?;
213+
build_table_of_contents_markdown(buffer, command_path.clone(), subcommand, depth + 1)?;
224214
}
225215

226216
Ok(())
@@ -418,12 +408,7 @@ fn build_command_markdown(
418408
write!(buffer, "\n\n")?;
419409

420410
for subcommand in command.get_subcommands().sorted_by_key(|c| c.get_name()) {
421-
build_command_markdown(
422-
buffer,
423-
command_path.clone(),
424-
subcommand,
425-
depth + 1,
426-
)?;
411+
build_command_markdown(buffer, command_path.clone(), subcommand, depth + 1)?;
427412
}
428413

429414
Ok(())
@@ -447,9 +432,7 @@ fn write_arg_markdown(buffer: &mut String, arg: &clap::Arg) -> fmt::Result {
447432
let value_name: String = match arg.get_value_names() {
448433
// TODO: What if multiple names are provided?
449434
Some([name, ..]) => name.to_string(),
450-
Some([]) => unreachable!(
451-
"clap Arg::get_value_names() returned Some(..) of empty list"
452-
),
435+
Some([]) => unreachable!("clap Arg::get_value_names() returned Some(..) of empty list"),
453436
None => arg.get_id().to_string().to_ascii_uppercase(),
454437
};
455438

@@ -460,26 +443,29 @@ fn write_arg_markdown(buffer: &mut String, arg: &clap::Arg) -> fmt::Result {
460443
} else {
461444
write!(buffer, "`-{short}`, `--{long}`")?
462445
}
463-
},
446+
}
464447
(Some(short), None) => {
465448
if arg.get_action().takes_values() {
466449
write!(buffer, "`-{short} <{value_name}>`")?
467450
} else {
468451
write!(buffer, "`-{short}`")?
469452
}
470-
},
453+
}
471454
(None, Some(long)) => {
472455
if arg.get_action().takes_values() {
473456
write!(buffer, "`--{} <{value_name}>`", long)?
474457
} else {
475458
write!(buffer, "`--{}`", long)?
476459
}
477-
},
460+
}
478461
(None, None) => {
479-
debug_assert!(arg.is_positional(), "unexpected non-positional Arg with neither short nor long name: {arg:?}");
462+
debug_assert!(
463+
arg.is_positional(),
464+
"unexpected non-positional Arg with neither short nor long name: {arg:?}"
465+
);
480466

481467
write!(buffer, "`<{value_name}>`",)?;
482-
},
468+
}
483469
}
484470

485471
if let Some(help) = arg.get_long_help() {
@@ -517,19 +503,17 @@ fn write_arg_markdown(buffer: &mut String, arg: &clap::Arg) -> fmt::Result {
517503
//--------------------
518504

519505
let possible_values = arg
520-
.get_possible_values()
521-
.unwrap_or_default()
506+
.get_value_parser()
507+
.possible_values()
522508
.into_iter()
509+
.flatten()
523510
.filter(|pv| !pv.is_hide_set())
524511
.collect::<Vec<_>>();
525512

526513
// Print possible values for options that take a value, but not for flags
527514
// that can only be either present or absent and do not take a value.
528-
if !possible_values.is_empty()
529-
&& !matches!(arg.get_action(), clap::ArgAction::SetTrue)
530-
{
531-
let any_have_help: bool =
532-
possible_values.iter().any(|pv| pv.get_help().is_some());
515+
if !possible_values.is_empty() && !matches!(arg.get_action(), clap::ArgAction::SetTrue) {
516+
let any_have_help: bool = possible_values.iter().any(|pv| pv.get_help().is_some());
533517

534518
if any_have_help {
535519
// If any of the possible values have help text, print them
@@ -548,7 +532,7 @@ fn write_arg_markdown(buffer: &mut String, arg: &clap::Arg) -> fmt::Result {
548532
.map(|pv| match pv.get_help() {
549533
Some(help) => {
550534
format!(" - `{}`:\n {}\n", pv.get_name(), help)
551-
},
535+
}
552536
None => format!(" - `{}`\n", pv.get_name()),
553537
})
554538
.collect::<Vec<String>>()

src/commands/build.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ pub struct BuildCommand {
2626
pub app_source: Option<PathBuf>,
2727

2828
/// Component ID to build. This can be specified multiple times. The default is all components.
29-
#[clap(short = 'c', long, multiple = true)]
29+
#[clap(short = 'c', long)]
3030
pub component_id: Vec<String>,
3131

3232
/// By default, if the application manifest specifies one or more deployment targets, Spin

src/commands/cloud.rs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -35,24 +35,24 @@ const DEFAULT_DEPLOY_PLUGIN: &str = "cloud";
3535
const DEPLOY_PLUGIN_ENV: &str = "SPIN_DEPLOY_PLUGIN";
3636

3737
impl DeployCommand {
38-
pub async fn run(self, app: clap::App<'_>) -> Result<()> {
39-
const CMD: &str = "deploy";
38+
pub async fn run(self, cmd: clap::Command<'_>) -> Result<()> {
39+
const SUBCMD: &str = "deploy";
4040

41-
let deploy_plugin = deployment_plugin(CMD)?;
42-
let mut cmd = vec![deploy_plugin, CMD.to_string()];
43-
cmd.append(&mut self.args.clone());
44-
execute_external_subcommand(cmd, app).await
41+
let deploy_plugin = deployment_plugin(SUBCMD)?;
42+
let mut subcmd = vec![deploy_plugin, SUBCMD.to_string()];
43+
subcmd.append(&mut self.args.clone());
44+
execute_external_subcommand(subcmd, cmd).await
4545
}
4646
}
4747

4848
impl LoginCommand {
49-
pub async fn run(self, app: clap::App<'_>) -> Result<()> {
50-
const CMD: &str = "login";
49+
pub async fn run(self, cmd: clap::Command<'_>) -> Result<()> {
50+
const SUBCMD: &str = "login";
5151

52-
let deploy_plugin = deployment_plugin(CMD)?;
53-
let mut cmd = vec![deploy_plugin, CMD.to_string()];
54-
cmd.append(&mut self.args.clone());
55-
execute_external_subcommand(cmd, app).await
52+
let deploy_plugin = deployment_plugin(SUBCMD)?;
53+
let mut subcmd = vec![deploy_plugin, SUBCMD.to_string()];
54+
subcmd.append(&mut self.args.clone());
55+
execute_external_subcommand(subcmd, cmd).await
5656
}
5757
}
5858

src/commands/external.rs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -53,15 +53,15 @@ pub fn predefined_externals() -> Vec<(String, String)> {
5353
/// indicate the plugin to execute. Passes all subsequent arguments on to the
5454
/// subprocess.
5555
pub async fn execute_external_subcommand(
56-
cmd: Vec<String>,
57-
app: clap::App<'_>,
56+
subcmd: Vec<String>,
57+
cmd: clap::Command<'_>,
5858
) -> anyhow::Result<()> {
59-
let (plugin_name, args, override_compatibility_check) = parse_subcommand(cmd)?;
59+
let (plugin_name, args, override_compatibility_check) = parse_subcommand(subcmd)?;
6060
let plugin_store = PluginStore::try_default()?;
6161
let plugin_version = ensure_plugin_available(
6262
&plugin_name,
6363
&plugin_store,
64-
app,
64+
cmd,
6565
override_compatibility_check,
6666
)
6767
.await?;
@@ -115,7 +115,7 @@ fn set_kill_on_ctrl_c(child: &tokio::process::Child) {
115115
async fn ensure_plugin_available(
116116
plugin_name: &str,
117117
plugin_store: &PluginStore,
118-
app: clap::App<'_>,
118+
cmd: clap::Command<'_>,
119119
override_compatibility_check: bool,
120120
) -> anyhow::Result<Option<String>> {
121121
let plugin_version = match plugin_store.read_plugin_manifest(plugin_name) {
@@ -130,7 +130,7 @@ async fn ensure_plugin_available(
130130
Some(manifest.version().to_owned())
131131
}
132132
Err(PluginError::NotFound(e)) => {
133-
consider_install(plugin_name, plugin_store, app, &e).await?
133+
consider_install(plugin_name, plugin_store, cmd, &e).await?
134134
}
135135
Err(e) => return Err(e.into()),
136136
};
@@ -140,7 +140,7 @@ async fn ensure_plugin_available(
140140
async fn consider_install(
141141
plugin_name: &str,
142142
plugin_store: &PluginStore,
143-
app: clap::App<'_>,
143+
cmd: clap::Command<'_>,
144144
e: &spin_plugins::error::NotFoundError,
145145
) -> anyhow::Result<Option<String>> {
146146
if predefined_externals()
@@ -176,7 +176,7 @@ async fn consider_install(
176176

177177
tracing::debug!("Tried to resolve {plugin_name} to plugin, got {e}");
178178
terminal::error!("'{plugin_name}' is not a known Spin command. See spin --help.\n");
179-
print_similar_commands(app, plugin_name);
179+
print_similar_commands(cmd, plugin_name);
180180
process::exit(2);
181181
}
182182

@@ -280,8 +280,8 @@ async fn report_badger_result(badger: tokio::task::JoinHandle<BadgerChecker>) {
280280
}
281281
}
282282

283-
fn print_similar_commands(app: clap::App, plugin_name: &str) {
284-
let similar = similar_commands(app, plugin_name);
283+
fn print_similar_commands(cmd: clap::Command, plugin_name: &str) {
284+
let similar = similar_commands(cmd, plugin_name);
285285
match similar.len() {
286286
0 => (),
287287
1 => eprintln!("The most similar command is:"),
@@ -295,8 +295,8 @@ fn print_similar_commands(app: clap::App, plugin_name: &str) {
295295
}
296296
}
297297

298-
fn similar_commands(app: clap::App, target: &str) -> Vec<String> {
299-
app.get_subcommands()
298+
fn similar_commands(cmd: clap::Command, target: &str) -> Vec<String> {
299+
cmd.get_subcommands()
300300
.filter_map(|sc| {
301301
let actual_name = undecorate(sc.get_name());
302302
if levenshtein::levenshtein(&actual_name, target) <= 2 {

src/commands/new.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,7 @@ pub struct TemplateNewCommandCore {
3333
pub template_id: Option<String>,
3434

3535
/// Filter templates to select by tags.
36-
#[clap(
37-
long = "tag",
38-
multiple_occurrences = true,
39-
conflicts_with = "template-id"
40-
)]
36+
#[clap(long = "tag", conflicts_with = "template-id")]
4137
pub tags: Vec<String>,
4238

4339
/// The directory in which to create the new application or component.
@@ -50,7 +46,7 @@ pub struct TemplateNewCommandCore {
5046
pub init: bool,
5147

5248
/// Parameter values to be passed to the template (in name=value format).
53-
#[clap(short = 'v', long = "value", multiple_occurrences = true)]
49+
#[clap(short = 'v', long = "value")]
5450
pub values: Vec<ParameterValue>,
5551

5652
/// A TOML file which contains parameter values in name = "value" format.

src/commands/registry.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ pub struct Push {
7373

7474
/// Specifies the OCI image manifest annotations (in key=value format).
7575
/// Any existing value will be overwritten. Can be used multiple times.
76-
#[clap(long = "annotation", parse(try_from_str = parse_kv))]
76+
#[clap(long = "annotation", value_parser = parse_kv)]
7777
pub annotations: Vec<(String, String)>,
7878
}
7979

0 commit comments

Comments
 (0)