From b41a9575d441ab5d0cea2110a1de92146bdd25e4 Mon Sep 17 00:00:00 2001 From: Dominik Nakamura Date: Wed, 21 Dec 2022 11:01:29 +0900 Subject: [PATCH] Update clap to v4 (#471) --- CHANGELOG.md | 1 + Cargo.lock | 20 ++++++-------------- Cargo.toml | 2 +- src/cmd/build.rs | 4 ++-- src/cmd/clean.rs | 6 +++--- src/cmd/config.rs | 4 ++-- src/cmd/serve.rs | 8 ++++---- src/cmd/watch.rs | 6 +++--- src/common.rs | 5 +++-- src/config/models.rs | 45 ++++++++++++++++++++++---------------------- src/main.rs | 19 +++++++++++++++---- 11 files changed, 62 insertions(+), 58 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ed963260..34e1d9aa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ Subheadings to categorize changes are `added, changed, deprecated, removed, fixe - Our website (trunkrs.dev) now only updates on new releases. - Additional attributes are now passed through script tags (fixes #429) - Updated internal http stack to axum v0.6.0. +- Updated CLI argument parser to clap v0.4. ### fixed - Nested WS proxies - if `backend=ws://localhost:8000/ws` is set, queries for `ws://localhost:8080/ws/entityX` will be linked with `ws://localhost:8000/ws/entityX` - Updated all dependencies in both Trunk and its examples, to fix currently open security advisories for old dependencies. diff --git a/Cargo.lock b/Cargo.lock index d5a0af14..5b3b521f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -257,26 +257,24 @@ dependencies = [ [[package]] name = "clap" -version = "3.2.22" +version = "4.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86447ad904c7fb335a790c9d7fe3d0d971dc523b8ccd1561a520de9a85302750" +checksum = "2148adefda54e14492fb9bddcc600b4344c5d1a3123bd666dcb939c6f0e0e57e" dependencies = [ "atty", "bitflags", "clap_derive", "clap_lex", - "indexmap", "once_cell", "strsim", "termcolor", - "textwrap", ] [[package]] name = "clap_derive" -version = "3.2.18" +version = "4.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea0c8bce528c4be4da13ea6fead8965e95b6073585a2f05204bd8f4119f82a65" +checksum = "0177313f9f02afc995627906bbd8967e2be069f5261954222dac78290c2b9014" dependencies = [ "heck", "proc-macro-error", @@ -287,9 +285,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.2.4" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" +checksum = "0d4198f73e42b4936b35b5bb248d81d2b595ecb170da0bac7655c54eedfa8da8" dependencies = [ "os_str_bytes", ] @@ -2131,12 +2129,6 @@ dependencies = [ "winapi 0.3.9", ] -[[package]] -name = "textwrap" -version = "0.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "949517c0cf1bf4ee812e2e07e08ab448e3ae0d23472aee8a06c985f0c8815b16" - [[package]] name = "thin-slice" version = "0.1.1" diff --git a/Cargo.toml b/Cargo.toml index 9862f300..5ec70fd4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,7 @@ axum = { version = "0.6", features = ["ws"] } bytes = "1" cargo-lock = "8" cargo_metadata = "0.15" -clap = { version = "3", features = ["derive", "env"] } +clap = { version = "4", features = ["derive", "env"] } console = "0.15" directories = "4" dunce = "1" diff --git a/src/cmd/build.rs b/src/cmd/build.rs index 5ddde856..5cc7dd2c 100644 --- a/src/cmd/build.rs +++ b/src/cmd/build.rs @@ -8,9 +8,9 @@ use crate::config::{ConfigOpts, ConfigOptsBuild}; /// Build the Rust WASM app and all of its assets. #[derive(Clone, Debug, Args)] -#[clap(name = "build")] +#[command(name = "build")] pub struct Build { - #[clap(flatten)] + #[command(flatten)] pub build: ConfigOptsBuild, } diff --git a/src/cmd/clean.rs b/src/cmd/clean.rs index d5eb7ece..28e6557a 100644 --- a/src/cmd/clean.rs +++ b/src/cmd/clean.rs @@ -11,15 +11,15 @@ use crate::tools::cache_dir; /// Clean output artifacts. #[derive(Args)] -#[clap(name = "clean")] +#[command(name = "clean")] pub struct Clean { - #[clap(flatten)] + #[command(flatten)] pub clean: ConfigOptsClean, /// Optionally clean any cached tools used by Trunk /// /// These tools are cached in a platform dependent "projects" dir. Removing them will cause /// them to be downloaded by Trunk next time they are needed. - #[clap(short, long)] + #[arg(short, long)] pub tools: bool, } diff --git a/src/cmd/config.rs b/src/cmd/config.rs index 8e530620..2d43b76a 100644 --- a/src/cmd/config.rs +++ b/src/cmd/config.rs @@ -7,9 +7,9 @@ use crate::config::ConfigOpts; /// Trunk config controls. #[derive(Clone, Debug, Args)] -#[clap(name = "config")] +#[command(name = "config")] pub struct Config { - #[clap(subcommand)] + #[command(subcommand)] action: ConfigSubcommands, } diff --git a/src/cmd/serve.rs b/src/cmd/serve.rs index 9887d884..7d38e9e4 100644 --- a/src/cmd/serve.rs +++ b/src/cmd/serve.rs @@ -9,13 +9,13 @@ use crate::serve::ServeSystem; /// Build, watch & serve the Rust WASM app and all of its assets. #[derive(Args)] -#[clap(name = "serve")] +#[command(name = "serve")] pub struct Serve { - #[clap(flatten)] + #[command(flatten)] pub build: ConfigOptsBuild, - #[clap(flatten)] + #[command(flatten)] pub watch: ConfigOptsWatch, - #[clap(flatten)] + #[command(flatten)] pub serve: ConfigOptsServe, } diff --git a/src/cmd/watch.rs b/src/cmd/watch.rs index 1c893df8..8ff6a7c7 100644 --- a/src/cmd/watch.rs +++ b/src/cmd/watch.rs @@ -9,11 +9,11 @@ use crate::watch::WatchSystem; /// Build & watch the Rust WASM app and all of its assets. #[derive(Args)] -#[clap(name = "watch")] +#[command(name = "watch")] pub struct Watch { - #[clap(flatten)] + #[command(flatten)] pub build: ConfigOptsBuild, - #[clap(flatten)] + #[command(flatten)] pub watch: ConfigOptsWatch, } diff --git a/src/common.rs b/src/common.rs index 6bb93555..dd92e715 100644 --- a/src/common.rs +++ b/src/common.rs @@ -1,5 +1,6 @@ //! Common functionality and types. +use std::convert::Infallible; use std::ffi::OsStr; use std::fmt::Debug; use std::fs::Metadata; @@ -22,10 +23,10 @@ static CWD: Lazy = Lazy::new(|| std::env::current_dir().expect("error getting current dir")); /// Ensure the given value for `--public-url` is formatted correctly. -pub fn parse_public_url(val: &str) -> String { +pub fn parse_public_url(val: &str) -> Result { let prefix = if !val.starts_with('/') { "/" } else { "" }; let suffix = if !val.ends_with('/') { "/" } else { "" }; - format!("{}{}{}", prefix, val, suffix) + Ok(format!("{}{}{}", prefix, val, suffix)) } /// A utility function to recursively copy a directory. diff --git a/src/config/models.rs b/src/config/models.rs index 6f9003ae..f60becb7 100644 --- a/src/config/models.rs +++ b/src/config/models.rs @@ -17,32 +17,31 @@ use crate::pipelines::PipelineStage; #[derive(Clone, Debug, Default, Deserialize, Args)] pub struct ConfigOptsBuild { /// The index HTML file to drive the bundling process [default: index.html] - #[clap(parse(from_os_str))] pub target: Option, /// Build in release mode [default: false] - #[clap(long)] + #[arg(long)] #[serde(default)] pub release: bool, /// The output dir for all final assets [default: dist] - #[clap(short, long, parse(from_os_str))] + #[arg(short, long)] pub dist: Option, /// The public URL from which assets are to be served [default: /] - #[clap(long, parse(from_str=parse_public_url))] + #[arg(long, value_parser = parse_public_url)] pub public_url: Option, /// Build without default features [default: false] - #[clap(long)] + #[arg(long)] #[serde(default)] pub no_default_features: bool, /// Build with all features [default: false] - #[clap(long)] + #[arg(long)] #[serde(default)] pub all_features: bool, /// A comma-separated list of features to activate, must not be used with all-features /// [default: ""] - #[clap(long)] + #[arg(long)] pub features: Option, /// Whether to include hash values in the output file names [default: true] - #[clap(long)] + #[arg(long)] pub filehash: Option, /// Optional pattern for the app loader script [default: None] /// @@ -51,7 +50,7 @@ pub struct ConfigOptsBuild { /// to key/value pairs provided in `pattern_params`. /// /// These values can only be provided via config file. - #[clap(skip)] + #[arg(skip)] #[serde(default)] pub pattern_script: Option, /// Optional pattern for the app preload element [default: None] @@ -61,10 +60,10 @@ pub struct ConfigOptsBuild { /// to key/value pairs provided in `pattern_params`. /// /// These values can only be provided via config file. - #[clap(skip)] + #[arg(skip)] #[serde(default)] pub pattern_preload: Option, - #[clap(skip)] + #[arg(skip)] #[serde(default)] /// Optional replacement parameters corresponding to the patterns provided in /// `pattern_script` and `pattern_preload`. @@ -86,10 +85,10 @@ pub struct ConfigOptsBuild { #[derive(Clone, Debug, Default, Deserialize, Args)] pub struct ConfigOptsWatch { /// Watch specific file(s) or folder(s) [default: build target parent folder] - #[clap(short, long, parse(from_os_str), value_name = "path")] + #[arg(short, long, value_name = "path")] pub watch: Option>, /// Paths to ignore [default: []] - #[clap(short, long, parse(from_os_str), value_name = "path")] + #[arg(short, long, value_name = "path")] pub ignore: Option>, } @@ -97,34 +96,34 @@ pub struct ConfigOptsWatch { #[derive(Clone, Debug, Default, Deserialize, Args)] pub struct ConfigOptsServe { /// The address to serve on [default: 127.0.0.1] - #[clap(long)] + #[arg(long)] pub address: Option, /// The port to serve on [default: 8080] - #[clap(long)] + #[arg(long)] pub port: Option, /// Open a browser tab once the initial build is complete [default: false] - #[clap(long)] + #[arg(long)] #[serde(default)] pub open: bool, /// A URL to which requests will be proxied [default: None] - #[clap(long = "proxy-backend")] + #[arg(long = "proxy-backend")] #[serde(default, deserialize_with = "deserialize_uri")] pub proxy_backend: Option, /// The URI on which to accept requests which are to be rewritten and proxied to backend /// [default: None] - #[clap(long = "proxy-rewrite")] + #[arg(long = "proxy-rewrite")] #[serde(default)] pub proxy_rewrite: Option, /// Configure the proxy for handling WebSockets [default: false] - #[clap(long = "proxy-ws")] + #[arg(long = "proxy-ws")] #[serde(default)] pub proxy_ws: bool, /// Configure the proxy to accept insecure requests [default: false] - #[clap(long = "proxy-insecure")] + #[arg(long = "proxy-insecure")] #[serde(default)] pub proxy_insecure: bool, /// Disable auto-reload of the web app [default: false] - #[clap(long = "no-autoreload")] + #[arg(long = "no-autoreload")] #[serde(default)] pub no_autoreload: bool, } @@ -133,10 +132,10 @@ pub struct ConfigOptsServe { #[derive(Clone, Debug, Default, Deserialize, Args)] pub struct ConfigOptsClean { /// The output dir for all final assets [default: dist] - #[clap(short, long, parse(from_os_str))] + #[arg(short, long)] pub dist: Option, /// Optionally perform a cargo clean [default: false] - #[clap(long)] + #[arg(long)] #[serde(default)] pub cargo: bool, } diff --git a/src/main.rs b/src/main.rs index d33445a1..c7bd49a1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -49,15 +49,15 @@ async fn main() -> Result<()> { /// Build, bundle & ship your Rust WASM application to the web. #[derive(Parser)] -#[clap(about, author, version, name = "trunk")] +#[command(about, author, version, name = "trunk")] struct Trunk { - #[clap(subcommand)] + #[command(subcommand)] action: TrunkSubcommands, /// Path to the Trunk config file [default: Trunk.toml] - #[clap(long, parse(from_os_str), env = "TRUNK_CONFIG")] + #[arg(long, env = "TRUNK_CONFIG")] pub config: Option, /// Enable verbose logging. - #[clap(short)] + #[arg(short)] pub v: bool, } @@ -87,3 +87,14 @@ enum TrunkSubcommands { /// Trunk config controls. Config(cmd::config::Config), } + +#[cfg(test)] +mod tests { + use crate::Trunk; + + #[test] + fn verify_cli() { + use clap::CommandFactory; + Trunk::command().debug_assert(); + } +}