diff --git a/Cargo.lock b/Cargo.lock index 62cf5ab301..e33e91178c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1272,23 +1272,6 @@ dependencies = [ "libloading", ] -[[package]] -name = "clap" -version = "3.2.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" -dependencies = [ - "atty", - "bitflags 1.3.2", - "clap_derive 3.2.25", - "clap_lex 0.2.4", - "indexmap 1.9.3", - "once_cell", - "strsim 0.10.0", - "termcolor", - "textwrap", -] - [[package]] name = "clap" version = "4.5.4" @@ -1296,7 +1279,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" dependencies = [ "clap_builder", - "clap_derive 4.5.4", + "clap_derive", ] [[package]] @@ -1307,21 +1290,9 @@ checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" dependencies = [ "anstream", "anstyle", - "clap_lex 0.7.0", + "clap_lex", "strsim 0.11.1", -] - -[[package]] -name = "clap_derive" -version = "3.2.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae6371b8bdc8b7d3959e9cf7b22d4435ef3e79e138688421ec654acf8c81b008" -dependencies = [ - "heck 0.4.1", - "proc-macro-error", - "proc-macro2", - "quote", - "syn 1.0.109", + "terminal_size", ] [[package]] @@ -1336,15 +1307,6 @@ dependencies = [ "syn 2.0.58", ] -[[package]] -name = "clap_lex" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" -dependencies = [ - "os_str_bytes", -] - [[package]] name = "clap_lex" version = "0.7.0" @@ -4007,7 +3969,7 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cc0bda45ed5b3a2904262c1bb91e526127aa70e7ef3758aba2ef93cf896b9b58" dependencies = [ - "clap 4.5.4", + "clap", "escape8259", "termcolor", "threadpool", @@ -5081,12 +5043,6 @@ dependencies = [ "pin-project-lite", ] -[[package]] -name = "os_str_bytes" -version = "6.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" - [[package]] name = "overload" version = "0.1.1" @@ -5539,30 +5495,6 @@ dependencies = [ "toml_edit 0.19.15", ] -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn 1.0.109", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote", - "version_check", -] - [[package]] name = "proc-macro2" version = "1.0.79" @@ -6994,7 +6926,7 @@ dependencies = [ "bytes", "cargo-target-dep", "chrono", - "clap 3.2.25", + "clap", "clearscreen 3.0.0", "comfy-table", "command-group", @@ -7696,7 +7628,7 @@ name = "spin-runtime-factors" version = "2.8.0-pre0" dependencies = [ "anyhow", - "clap 3.2.25", + "clap", "spin-common", "spin-factor-key-value", "spin-factor-llm", @@ -7831,7 +7763,7 @@ name = "spin-trigger" version = "2.8.0-pre0" dependencies = [ "anyhow", - "clap 3.2.25", + "clap", "ctrlc", "futures", "sanitize-filename", @@ -7861,7 +7793,7 @@ version = "2.8.0-pre0" dependencies = [ "anyhow", "async-trait", - "clap 3.2.25", + "clap", "futures", "futures-util", "http 1.1.0", @@ -8212,6 +8144,16 @@ dependencies = [ "termcolor", ] +[[package]] +name = "terminal_size" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7" +dependencies = [ + "rustix 0.38.32", + "windows-sys 0.48.0", +] + [[package]] name = "terminfo" version = "0.8.0" @@ -8281,12 +8223,6 @@ dependencies = [ "wasmtime-wasi-http", ] -[[package]] -name = "textwrap" -version = "0.16.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" - [[package]] name = "thiserror" version = "1.0.63" @@ -8392,7 +8328,7 @@ checksum = "aea68938177975ab09da68552b720eac941779ff386baceaf77e0f5f9cea645f" dependencies = [ "aho-corasick 0.7.20", "cached-path", - "clap 4.5.4", + "clap", "derive_builder 0.12.0", "dirs 4.0.0", "esaxx-rs", @@ -9102,7 +9038,7 @@ dependencies = [ "async-recursion", "async-trait", "bytes", - "clap 4.5.4", + "clap", "dialoguer 0.11.0", "dirs 5.0.1", "futures-util", diff --git a/Cargo.toml b/Cargo.toml index 78a8ae3d51..ddd4fd9e69 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,7 @@ anyhow = { workspace = true } async-trait = { workspace = true } bytes = { workspace = true } chrono = "0.4" -clap = { version = "3.2.24", features = ["derive", "env"] } +clap = { version = "4", features = ["derive", "env", "string", "wrap_help"] } clearscreen = "3" comfy-table = "7" command-group = "2" diff --git a/crates/componentize/tests/case-helper/Cargo.toml b/crates/componentize/tests/case-helper/Cargo.toml index e02de206ad..4ca232446f 100644 --- a/crates/componentize/tests/case-helper/Cargo.toml +++ b/crates/componentize/tests/case-helper/Cargo.toml @@ -5,7 +5,7 @@ edition = "2021" [dependencies] anyhow = "1" -clap = { version = "~4.4", features = ["derive", "env"] } +clap = { version = "4.5", features = ["derive", "env"] } getrandom = "0.2.12" [workspace] diff --git a/crates/runtime-factors/Cargo.toml b/crates/runtime-factors/Cargo.toml index 7bea71664a..a1f4fe5152 100644 --- a/crates/runtime-factors/Cargo.toml +++ b/crates/runtime-factors/Cargo.toml @@ -15,7 +15,7 @@ llm-cublas = ["spin-factor-llm/llm-cublas"] [dependencies] anyhow = { workspace = true } -clap = { version = "3.1.18", features = ["derive", "env"] } +clap = { version = "4", features = ["derive", "env"] } spin-common = { path = "../common" } spin-factor-key-value = { path = "../factor-key-value" } spin-factor-llm = { path = "../factor-llm" } diff --git a/crates/runtime-factors/src/lib.rs b/crates/runtime-factors/src/lib.rs index 8c7bd97d7d..b684fa3a1f 100644 --- a/crates/runtime-factors/src/lib.rs +++ b/crates/runtime-factors/src/lib.rs @@ -94,7 +94,7 @@ pub struct TriggerAppArgs { /// Set a key/value pair (key=value) in the application's /// default store. Any existing value will be overwritten. /// Can be used multiple times. - #[clap(long = "key-value", parse(try_from_str = parse_kv))] + #[clap(long = "key-value", value_parser(parse_kv))] pub key_values: Vec<(String, String)>, /// Run a SQLite statement such as a migration against the default database. diff --git a/crates/trigger-http/Cargo.toml b/crates/trigger-http/Cargo.toml index d0d4d01d01..86bce9062b 100644 --- a/crates/trigger-http/Cargo.toml +++ b/crates/trigger-http/Cargo.toml @@ -10,7 +10,7 @@ doctest = false [dependencies] anyhow = { workspace = true } async-trait = { workspace = true } -clap = "3" +clap = "4" futures = { workspace = true } futures-util = "0.3" http = { workspace = true } diff --git a/crates/trigger-http/src/lib.rs b/crates/trigger-http/src/lib.rs index 85a7e108cd..6712c865b8 100644 --- a/crates/trigger-http/src/lib.rs +++ b/crates/trigger-http/src/lib.rs @@ -44,11 +44,11 @@ pub struct CliArgs { pub address: SocketAddr, /// The path to the certificate to use for https, if this is not set, normal http will be used. The cert should be in PEM format - #[clap(long, env = "SPIN_TLS_CERT", requires = "tls-key")] + #[clap(long, env = "SPIN_TLS_CERT", requires = "tls_key")] pub tls_cert: Option, /// The path to the certificate key to use for https, if this is not set, normal http will be used. The key should be in PKCS#8 format - #[clap(long, env = "SPIN_TLS_KEY", requires = "tls-cert")] + #[clap(long, env = "SPIN_TLS_KEY", requires = "tls_cert")] pub tls_key: Option, } diff --git a/crates/trigger/Cargo.toml b/crates/trigger/Cargo.toml index faa059120f..04bf00441d 100644 --- a/crates/trigger/Cargo.toml +++ b/crates/trigger/Cargo.toml @@ -16,7 +16,7 @@ unsafe-aot-compilation = [] [dependencies] anyhow = { workspace = true } -clap = { version = "3.1.18", features = ["derive", "env"] } +clap = { version = "4", features = ["derive", "env", "wrap_help"] } ctrlc = { version = "3.2", features = ["termination"] } futures = { workspace = true } sanitize-filename = "0.5" diff --git a/crates/trigger/src/cli.rs b/crates/trigger/src/cli.rs index 720ff1bdd7..28bdc11031 100644 --- a/crates/trigger/src/cli.rs +++ b/crates/trigger/src/cli.rs @@ -8,7 +8,7 @@ use std::path::PathBuf; use std::{future::Future, sync::Arc}; use anyhow::{Context, Result}; -use clap::{Args, IntoApp, Parser}; +use clap::{Args, CommandFactory, Parser}; use spin_app::App; use spin_common::sloth; use spin_common::ui::quoted_path; @@ -38,8 +38,9 @@ pub const SPIN_WORKING_DIR: &str = "SPIN_WORKING_DIR"; /// A command that runs a TriggerExecutor. #[derive(Parser, Debug)] #[clap( - usage = "spin [COMMAND] [OPTIONS]", - next_help_heading = help_heading::() + next_help_heading = help_heading::(), + styles = help_styles(), + max_term_width = 100, )] pub struct FactorsTriggerCommand, B: RuntimeFactorsBuilder> { /// Log directory for the stdout and stderr of components. Setting to @@ -58,7 +59,7 @@ pub struct FactorsTriggerCommand, B: RuntimeFactorsBuilde long = "disable-cache", env = DISABLE_WASMTIME_CACHE, conflicts_with = WASMTIME_CACHE_FILE, - takes_value = false, + num_args = 0, )] pub disable_cache: bool, @@ -79,7 +80,7 @@ pub struct FactorsTriggerCommand, B: RuntimeFactorsBuilde #[clap( name = FOLLOW_LOG_OPT, long = "follow", - multiple_occurrences = true, + num_args = 1, )] pub follow_components: Vec, @@ -122,6 +123,15 @@ pub struct FactorsTriggerCommand, B: RuntimeFactorsBuilde pub launch_metadata_only: bool, } +/// The styles of the help output. +fn help_styles() -> clap::builder::Styles { + clap::builder::Styles::styled() + .header(clap::builder::styling::AnsiColor::Yellow.on_default()) + .usage(clap::builder::styling::AnsiColor::Green.on_default()) + .literal(clap::builder::styling::AnsiColor::Green.on_default()) + .placeholder(clap::builder::styling::AnsiColor::Green.on_default()) +} + /// Configuration options that are common to all triggers. #[derive(Debug, Default)] pub struct FactorsConfig { diff --git a/examples/spin-timer/Cargo.toml b/examples/spin-timer/Cargo.toml index b16e49b471..60dbe46373 100644 --- a/examples/spin-timer/Cargo.toml +++ b/examples/spin-timer/Cargo.toml @@ -6,7 +6,7 @@ edition = "2021" [dependencies] anyhow = "1.0.68" -clap = { version = "3.1.15", features = ["derive", "env"] } +clap = { version = "4", features = ["derive", "env"] } futures = "0.3.25" serde = "1.0.188" spin-factors = { path = "../../crates/factors" } diff --git a/src/bin/spin.rs b/src/bin/spin.rs index e3ba655040..6f17dc0b4f 100644 --- a/src/bin/spin.rs +++ b/src/bin/spin.rs @@ -50,13 +50,13 @@ async fn _main() -> anyhow::Result<()> { let mut cmd = SpinApp::command(); for plugin in &plugin_help_entries { let subcmd = clap::Command::new(plugin.display_text()) - .about(plugin.about.as_str()) + .about(plugin.about.as_str().to_owned()) .allow_hyphen_values(true) .disable_help_flag(true) .arg( clap::Arg::new("command") .allow_hyphen_values(true) - .multiple_values(true), + .num_args(1), ); cmd = cmd.subcommand(subcmd); } @@ -107,7 +107,11 @@ fn version() -> &'static str { #[derive(Parser)] #[clap( name = "spin", - version = version() + version = version(), + // Display help in alphabetical order instead of default WYSIWYG order. + next_display_order = None, + styles= spin_cli::commands::help_styles(), + max_term_width = 100, )] enum SpinApp { #[clap(subcommand, alias = "template")] @@ -148,7 +152,7 @@ enum TriggerCommands { impl SpinApp { /// The main entry point to Spin. - pub async fn run(self, app: clap::Command<'_>) -> Result<(), Error> { + pub async fn run(self, app: clap::Command) -> Result<(), Error> { match self { Self::Templates(cmd) => cmd.run().await, Self::Up(cmd) => cmd.run().await, diff --git a/src/commands.rs b/src/commands.rs index ad8f039728..cb7e3912b3 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -20,3 +20,12 @@ pub mod templates; pub mod up; /// Command for rebuilding and restarting a Spin app when files change. pub mod watch; + +/// The styles of the help output. +pub fn help_styles() -> clap::builder::Styles { + clap::builder::Styles::styled() + .header(clap::builder::styling::AnsiColor::Yellow.on_default()) + .usage(clap::builder::styling::AnsiColor::Green.on_default()) + .literal(clap::builder::styling::AnsiColor::Green.on_default()) + .placeholder(clap::builder::styling::AnsiColor::Green.on_default()) +} diff --git a/src/commands/build.rs b/src/commands/build.rs index 32bb7b8e13..1d82763749 100644 --- a/src/commands/build.rs +++ b/src/commands/build.rs @@ -24,7 +24,7 @@ pub struct BuildCommand { pub app_source: PathBuf, /// Component ID to build. This can be specified multiple times. The default is all components. - #[clap(short = 'c', long, multiple = true)] + #[clap(short = 'c', long, num_args = 1)] pub component_id: Vec, /// Run the application after building. diff --git a/src/commands/cloud.rs b/src/commands/cloud.rs index 870120ad0c..275f1c191a 100644 --- a/src/commands/cloud.rs +++ b/src/commands/cloud.rs @@ -27,7 +27,7 @@ pub struct LoginCommand { } impl DeployCommand { - pub async fn run(self, app: clap::App<'_>) -> Result<()> { + pub async fn run(self, app: clap::Command) -> Result<()> { let mut cmd = vec!["cloud".to_string(), "deploy".to_string()]; cmd.append(&mut self.args.clone()); execute_external_subcommand(cmd, app).await @@ -35,7 +35,7 @@ impl DeployCommand { } impl LoginCommand { - pub async fn run(self, app: clap::App<'_>) -> Result<()> { + pub async fn run(self, app: clap::Command) -> Result<()> { let mut cmd = vec!["cloud".to_string(), "login".to_string()]; cmd.append(&mut self.args.clone()); execute_external_subcommand(cmd, app).await diff --git a/src/commands/external.rs b/src/commands/external.rs index 6ad91cb718..4d6bf52cc6 100644 --- a/src/commands/external.rs +++ b/src/commands/external.rs @@ -54,14 +54,14 @@ pub fn predefined_externals() -> Vec<(String, String)> { /// subprocess. pub async fn execute_external_subcommand( cmd: Vec, - app: clap::App<'_>, + command: clap::Command, ) -> anyhow::Result<()> { let (plugin_name, args, override_compatibility_check) = parse_subcommand(cmd)?; let plugin_store = PluginStore::try_default()?; let plugin_version = ensure_plugin_available( &plugin_name, &plugin_store, - app, + command, override_compatibility_check, ) .await?; @@ -115,7 +115,7 @@ fn set_kill_on_ctrl_c(child: &tokio::process::Child) { async fn ensure_plugin_available( plugin_name: &str, plugin_store: &PluginStore, - app: clap::App<'_>, + command: clap::Command, override_compatibility_check: bool, ) -> anyhow::Result> { let plugin_version = match plugin_store.read_plugin_manifest(plugin_name) { @@ -130,7 +130,7 @@ async fn ensure_plugin_available( Some(manifest.version().to_owned()) } Err(PluginError::NotFound(e)) => { - consider_install(plugin_name, plugin_store, app, &e).await? + consider_install(plugin_name, plugin_store, command, &e).await? } Err(e) => return Err(e.into()), }; @@ -140,7 +140,7 @@ async fn ensure_plugin_available( async fn consider_install( plugin_name: &str, plugin_store: &PluginStore, - app: clap::App<'_>, + command: clap::Command, e: &spin_plugins::error::NotFoundError, ) -> anyhow::Result> { if predefined_externals() @@ -176,7 +176,7 @@ async fn consider_install( tracing::debug!("Tried to resolve {plugin_name} to plugin, got {e}"); terminal::error!("'{plugin_name}' is not a known Spin command. See spin --help.\n"); - print_similar_commands(app, plugin_name); + print_similar_commands(command, plugin_name); process::exit(2); } @@ -279,8 +279,8 @@ async fn report_badger_result(badger: tokio::task::JoinHandle) { } } -fn print_similar_commands(app: clap::App, plugin_name: &str) { - let similar = similar_commands(app, plugin_name); +fn print_similar_commands(command: clap::Command, plugin_name: &str) { + let similar = similar_commands(command, plugin_name); match similar.len() { 0 => (), 1 => eprintln!("The most similar command is:"), @@ -294,8 +294,9 @@ fn print_similar_commands(app: clap::App, plugin_name: &str) { } } -fn similar_commands(app: clap::App, target: &str) -> Vec { - app.get_subcommands() +fn similar_commands(command: clap::Command, target: &str) -> Vec { + command + .get_subcommands() .filter_map(|sc| { let actual_name = undecorate(sc.get_name()); if levenshtein::levenshtein(&actual_name, target) <= 2 { diff --git a/src/commands/new.rs b/src/commands/new.rs index 97096529cd..2ffcee682a 100644 --- a/src/commands/new.rs +++ b/src/commands/new.rs @@ -33,11 +33,7 @@ pub struct TemplateNewCommandCore { pub template_id: Option, /// Filter templates to select by tags. - #[clap( - long = "tag", - multiple_occurrences = true, - conflicts_with = "template-id" - )] + #[clap(long = "tag", num_args = 1, conflicts_with = "template_id")] pub tags: Vec, /// The directory in which to create the new application or component. @@ -46,11 +42,11 @@ pub struct TemplateNewCommandCore { pub output_path: Option, /// Create the new application or component in the current directory. - #[clap(long = "init", takes_value = false, group = "location")] + #[clap(long = "init", num_args = 0, group = "location")] pub init: bool, /// Parameter values to be passed to the template (in name=value format). - #[clap(short = 'v', long = "value", multiple_occurrences = true)] + #[clap(short = 'v', long = "value", num_args = 1)] pub values: Vec, /// A TOML file which contains parameter values in name = "value" format. @@ -61,20 +57,16 @@ pub struct TemplateNewCommandCore { /// An optional argument that allows to skip prompts for the manifest file /// by accepting the defaults if available on the template - #[clap(short = 'a', long = "accept-defaults", takes_value = false)] + #[clap(short = 'a', long = "accept-defaults", num_args = 0)] pub accept_defaults: bool, /// An optional argument that allows to skip creating .gitignore - #[clap(long = "no-vcs", takes_value = false)] + #[clap(long = "no-vcs", num_args = 0)] pub no_vcs: bool, /// If the output directory already contains files, generate the new files into /// it without confirming, overwriting any existing files with the same names. - #[clap( - long = "allow-overwrite", - alias = "allow-overwrites", - takes_value = false - )] + #[clap(long = "allow-overwrite", alias = "allow-overwrites", num_args = 0)] pub allow_overwrite: bool, } @@ -257,7 +249,7 @@ impl TemplateNewCommandCore { } } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct ParameterValue { pub name: String, pub value: String, diff --git a/src/commands/plugins.rs b/src/commands/plugins.rs index fc2385ecf3..d007c3f6f3 100644 --- a/src/commands/plugins.rs +++ b/src/commands/plugins.rs @@ -91,11 +91,11 @@ pub struct Install { pub remote_manifest_src: Option, /// Skips prompt to accept the installation of the plugin. - #[clap(short = 'y', long = "yes", takes_value = false)] + #[clap(short = 'y', long = "yes", num_args = 0)] pub yes_to_all: bool, /// Overrides a failed compatibility check of the plugin with the current version of Spin. - #[clap(long = PLUGIN_OVERRIDE_COMPATIBILITY_CHECK_FLAG, takes_value = false)] + #[clap(long = PLUGIN_OVERRIDE_COMPATIBILITY_CHECK_FLAG, num_args = 0)] pub override_compatibility_check: bool, /// Specific version of a plugin to be install from the centralized plugins @@ -181,7 +181,7 @@ pub struct Upgrade { conflicts_with = PLUGIN_NAME_OPT, conflicts_with = PLUGIN_REMOTE_PLUGIN_MANIFEST_OPT, conflicts_with = PLUGIN_LOCAL_PLUGIN_MANIFEST_OPT, - takes_value = false, + num_args = 0 )] pub all: bool, @@ -204,11 +204,11 @@ pub struct Upgrade { pub remote_manifest_src: Option, /// Skips prompt to accept the installation of the plugin[s]. - #[clap(short = 'y', long = "yes", takes_value = false)] + #[clap(short = 'y', long = "yes", num_args = 0)] pub yes_to_all: bool, /// Overrides a failed compatibility check of the plugin with the current version of Spin. - #[clap(long = PLUGIN_OVERRIDE_COMPATIBILITY_CHECK_FLAG, takes_value = false)] + #[clap(long = PLUGIN_OVERRIDE_COMPATIBILITY_CHECK_FLAG, num_args = 0)] pub override_compatibility_check: bool, /// Specific version of a plugin to be install from the centralized plugins @@ -224,7 +224,7 @@ pub struct Upgrade { pub version: Option, /// Allow downgrading a plugin's version. - #[clap(short = 'd', long = "downgrade", takes_value = false)] + #[clap(short = 'd', long = "downgrade", num_args = 0)] pub downgrade: bool, } @@ -571,15 +571,15 @@ fn latest_and_rest( #[derive(Parser, Debug)] pub struct List { /// List only installed plugins. - #[clap(long = "installed", takes_value = false, group = "which")] + #[clap(long = "installed", num_args = 0, group = "which")] pub installed: bool, /// List all versions of plugins. This is the default behaviour. - #[clap(long = "all", takes_value = false, group = "which")] + #[clap(long = "all", num_args = 0, group = "which")] pub all: bool, /// List latest and installed versions of plugins. - #[clap(long = "summary", takes_value = false, group = "which")] + #[clap(long = "summary", num_args = 0, group = "which")] pub summary: bool, /// Filter the list to plugins containing this string. diff --git a/src/commands/registry.rs b/src/commands/registry.rs index 67427fc8fa..4c05737ed3 100644 --- a/src/commands/registry.rs +++ b/src/commands/registry.rs @@ -46,12 +46,12 @@ pub struct Push { name = INSECURE_OPT, short = 'k', long = "insecure", - takes_value = false, + num_args = 0, )] pub insecure: bool, /// Specifies to perform `spin build` before pushing the application. - #[clap(long, takes_value = false, env = ALWAYS_BUILD_ENV)] + #[clap(long, num_args = 0, env = ALWAYS_BUILD_ENV)] pub build: bool, /// Reference in the registry of the Spin application. @@ -65,7 +65,7 @@ pub struct Push { /// Specifies the OCI image manifest annotations (in key=value format). /// Any existing value will be overwritten. Can be used multiple times. - #[clap(long = "annotation", parse(try_from_str = parse_kv))] + #[clap(long = "annotation", value_parser(parse_kv))] pub annotations: Vec<(String, String)>, } @@ -110,7 +110,7 @@ pub struct Pull { name = INSECURE_OPT, short = 'k', long = "insecure", - takes_value = false, + num_args = 0 )] pub insecure: bool, @@ -148,11 +148,7 @@ pub struct Login { pub password: Option, /// Take the password from stdin - #[clap( - long = "password-stdin", - takes_value = false, - conflicts_with = "password" - )] + #[clap(long = "password-stdin", num_args = 0, conflicts_with = "password")] pub password_stdin: bool, /// OCI registry server (e.g. ghcr.io) diff --git a/src/commands/templates.rs b/src/commands/templates.rs index aa9367d09f..50bdf527e5 100644 --- a/src/commands/templates.rs +++ b/src/commands/templates.rs @@ -458,7 +458,7 @@ impl Uninstall { #[derive(Parser, Debug)] pub struct List { /// Filter templates matching all provided tags. - #[clap(long = "tag", multiple_occurrences = true)] + #[clap(long = "tag", num_args = 1)] pub tags: Vec, /// The format in which to list the templates. @@ -466,7 +466,7 @@ pub struct List { pub format: ListFormat, /// Whether to show additional template details in the list. - #[clap(long = "verbose", takes_value = false)] + #[clap(long = "verbose", num_args = 0)] pub verbose: bool, } diff --git a/src/commands/up.rs b/src/commands/up.rs index 87f5d61cf3..f871d68d82 100644 --- a/src/commands/up.rs +++ b/src/commands/up.rs @@ -40,7 +40,10 @@ const MULTI_TRIGGER_LET_ALL_START: tokio::time::Duration = tokio::time::Duration #[clap( about = "Start the Spin application", allow_hyphen_values = true, - disable_help_flag = true + disable_help_flag = true, + // We need to reapply styles here because the `help` field is handled manually. + styles= crate::commands::help_styles(), + max_term_width = 100, )] pub struct UpCommand { #[clap(short = 'h', long = "help")] @@ -83,12 +86,12 @@ pub struct UpCommand { name = INSECURE_OPT, short = 'k', long = "insecure", - takes_value = false, + num_args = 0, )] pub insecure: bool, /// Pass an environment variable (key=value) to all components of the application. - #[clap(short = 'e', long = "env", parse(try_from_str = parse_env_var))] + #[clap(short = 'e', long = "env", value_parser(parse_env_var))] pub env: Vec<(String, String)>, /// Temporary directory for the static assets of the components. @@ -104,13 +107,13 @@ pub struct UpCommand { /// /// This allows you to update the assets on the host filesystem such that the updates are visible to the guest /// without a restart. This cannot be used with registry apps or apps which use file patterns and/or exclusions. - #[clap(long, takes_value = false)] + #[clap(long, num_args = 0)] pub direct_mounts: bool, /// For local apps, specifies to perform `spin build` before running the application. /// /// This is ignored on remote applications, as they are already built. - #[clap(long, takes_value = false, env = ALWAYS_BUILD_ENV)] + #[clap(long, num_args = 0, env = ALWAYS_BUILD_ENV)] pub build: bool, /// All other args, to be passed through to the trigger