diff --git a/.clippy.toml b/.clippy.toml index 3b66266f..6bfeada7 100644 --- a/.clippy.toml +++ b/.clippy.toml @@ -1 +1 @@ -msrv = "1.61" +msrv = "1.62" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index efe8c2c3..71c33910 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -26,7 +26,7 @@ jobs: # pinned (MSRV) rust version :: ubuntu - build: msrv os: ubuntu-18.04 - rust: 1.61.0 + rust: 1.62.0 # latest rust stable :: ubuntu - build: stable diff --git a/Cargo.lock b/Cargo.lock index 3d1d536b..1eb41f4a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -519,26 +519,24 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "clap" -version = "3.2.22" +version = "4.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86447ad904c7fb335a790c9d7fe3d0d971dc523b8ccd1561a520de9a85302750" +checksum = "0a1af219c3e254a8b4649d6ddaef886b2015089f35f2ac5e1db31410c0566ab8" dependencies = [ "atty", "bitflags", "clap_derive", "clap_lex", - "indexmap", "once_cell", "strsim", "termcolor", - "textwrap", ] [[package]] name = "clap_derive" -version = "3.2.18" +version = "4.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea0c8bce528c4be4da13ea6fead8965e95b6073585a2f05204bd8f4119f82a65" +checksum = "cd114ae53ce5a0670f43d2f169c1cd26c69b4896b0c121900cf1e4d06d67316c" dependencies = [ "heck", "proc-macro-error", @@ -549,9 +547,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", ] @@ -1509,9 +1507,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.41" +version = "1.0.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdcc2916cde080c1876ff40292a396541241fe0072ef928cd76582e9ea5d60d2" +checksum = "94e2ef8dbfc347b10c094890f778ee2e36ca9bb4262e86dc99cd217e35f3470b" dependencies = [ "unicode-ident", ] @@ -1989,12 +1987,6 @@ dependencies = [ "rand", ] -[[package]] -name = "textwrap" -version = "0.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "949517c0cf1bf4ee812e2e07e08ab448e3ae0d23472aee8a06c985f0c8815b16" - [[package]] name = "thiserror" version = "1.0.37" diff --git a/Cargo.toml b/Cargo.toml index 057ca5e7..2f66acc3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,7 @@ description = "Find your minimum supported Rust version (MSRV)!" license = "Apache-2.0 OR MIT" edition = "2018" repository = "https://github.com/foresterre/cargo-msrv" -rust-version = "1.61" +rust-version = "1.62" keywords = ["msrv", "rust-version", "toolchain", "find", "minimum"] categories = ["development-tools", "development-tools::cargo-plugins", "command-line-utilities"] @@ -25,7 +25,7 @@ tag-name = "v{{version}}" [dependencies] # Used for parsing cli arguments. -clap = { version = "3.2.22", features = ["derive"] } +clap = { version = "4.0.7", features = ["derive"] } # UI indicatif = "0.17.1" diff --git a/README.md b/README.md index a2fbd273..069a635b 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ This crate can assist you in finding the Minimum Supported Rust Version for a crate. In this readme you'll find everything to get you started. You can find more detailed explanations in the -[cargo-msrv book](https://foresterre.github.io/cargo-msrv/index.html). +[cargo-msrv book](https://foresterre.github.io/cargo-msrv/index.html). ### Install @@ -26,7 +26,7 @@ From the Arch Linux [community repository](https://archlinux.org/packages/commun ### Usage -* [`cargo msrv`](https://foresterre.github.io/cargo-msrv/commands/find.html) or [`cargo msrv --linear`](https://foresterre.github.io/cargo-msrv/commands/find.html) to find the MSRV for a Cargo project in your current working directory. +* [`cargo msrv`](https://foresterre.github.io/cargo-msrv/commands/find.html) or [`cargo msrv --linear`](https://foresterre.github.io/cargo-msrv/commands/find.html) to find the MSRV for a Cargo project in your current working directory. * [`cargo msrv --path `](https://foresterre.github.io/cargo-msrv/commands/find.html) to find the MSRV for a Cargo project in the `` directory. * [`cargo msrv -- `](https://foresterre.github.io/cargo-msrv/commands/find.html) to use `` as the compatibility check which decides whether a Rust version is compatible or not. This command should be runnable through rustup as `rustup run `. @@ -34,7 +34,7 @@ From the Arch Linux [community repository](https://archlinux.org/packages/commun * A crate author may specify the MSRV using the `package.rust-version` (Rust >=1.56) or the `package.metadata.msrv` key in the 'Cargo.toml' manifest. See the [book](https://foresterre.github.io/cargo-msrv/commands/list.html#description) for a more detailed description. -* [`cargo msrv list`](https://foresterre.github.io/cargo-msrv/commands/list.html) to list the MSRV's of your dependencies as specified by their authors +* [`cargo msrv list`](https://foresterre.github.io/cargo-msrv/commands/list.html) to list the MSRV's of your dependencies as specified by their authors * [`cargo msrv show`](https://foresterre.github.io/cargo-msrv/commands/show.html) to show the currently specified MSRV Please refer to the [commands](https://foresterre.github.io/cargo-msrv/commands/index.html) chapter in the cargo-msrv @@ -43,99 +43,141 @@ book for more detailed descriptions of the supported (sub) commands. **Options** ``` -cargo-msrv -Martijn Gribnau -Helps with finding the Minimal Supported Rust Version (MSRV) - -USAGE: - cargo msrv [OPTIONS] or cargo-msrv [OPTIONS] - -OPTIONS: - --bisect - Use a binary search to find the MSRV instead of a linear search - - -h, --help - Prints help information - - --include-all-patch-releases - Include all patch releases, instead of only the last - - --linear - Use a linear search to find the MSRV, by checking toolchains from latest to earliest - - --ignore-lockfile - Temporarily removes the lockfile, so it will not interfere with the building process. This is important when - testing against Rust versions prior to 1.38.0, for which Cargo does not recognize the new v2 lockfile. - --log-level - Specify the verbosity of logs the program should output [default: info] [possible values: - error, warn, info, debug, trace] - --log-target - Specify where the program should output its logs [default: file] [possible values: file, - stdout] - --max - Latest (most recent) version to take into account.Version must match a valid Rust toolchain, and be semver - compatible. [aliases: maximum] - --min - Earliest (least recent) version to take into account. Version must match a valid Rust toolchain, and be - semver compatible. Edition aliases may also be used. [aliases: minimum] - --no-check-feedback - If provided, the outcome of each individual check will not be printed. - - --no-log - Disable logging - - --no-read-min-edition - If provided, the 'package.edition' value in the Cargo.toml will not be used to reduce search space. - - --output-format - Output status messages in machine-readable format. Machine-readable status updates will be printed in the - requested format to stdout. [possible values: json, void] - --release-source - Select the rust-releases source to use as the release index [default: rust-changelog] [possible - values: rust-changelog, rust-dist] - --path - Path to the cargo project directory - - --target - Check against a custom target (instead of the rustup default) - - --toolchain-file - Output a rust-toolchain file with the MSRV as toolchain. The toolchain file will pin the Rust version for - this crate. See https://rust-lang.github.io/rustup/overrides.html#the-toolchain-file for more. - -V, --version - Prints version information - - --verify - Verify the MSRV defined in the 'package.rust-version' or the 'package.metadata.msrv' key in Cargo.toml. When - this flag is present, cargo-msrv will not attempt to determine the true MSRV. Instead it attempts to verify - whether for the specified MSRV, the `check` command passes. This is similar to how we determine whether a - Rust toolchain version is compatible for your crate or not. DEPRECATED: use the `cargo msrv verify` - subcommand instead. - -ARGS: - ... - If given, this command is used to validate if a Rust version is compatible. Should be available to rustup, - i.e. the command should work like so: `rustup run `. The default check action is `cargo - check --all`. - -SUBCOMMANDS: - help - Prints this message or the help of the given subcommand(s) - - list - List the MSRV's specified by dependency crate authors. - - show - Show the MSRV of your crate, as specified in the Cargo manifest. - - verify - Verify whether the MSRV is satisfiable. The MSRV must be specified using the 'package.rust-version' or - 'package.metadata.msrv' key in the Cargo.toml manifest. - -An argument provided after two dashes (`--`), will be interpreted as a custom command `check` command, used to validate -whether a Rust toolchain version is compatible. The default `check` command is "cargo build". A custom `check` command -should be runnable by rustup, as they will be passed on to rustup like so: `rustup run `. You'll -only need to provide the part. +Find your Minimum Supported Rust Version! + +Usage: cargo msrv [OPTIONS] [-- ...] [COMMAND] + +Commands: + list + Display the MSRV's of dependencies + set + Set the MSRV of the current crate to a given Rust version + show + Show the MSRV of your crate, as specified in the Cargo manifest + verify + Verify whether the MSRV is satisfiable. The MSRV must be specified using the 'package.rust-version' or 'package.metadata.msrv' key in the Cargo.toml manifest + help + Print this message or the help of the given subcommand(s) + +Options: + -h, --help + Print help information (use `-h` for a summary) + + -V, --version + Print version information + +Find MSRV options: + --bisect + Use a binary search to find the MSRV (default) + + When the search space is sufficiently large, which is common, this is much faster than a linear search. A binary search will approximately halve the search space for each Rust version checked for compatibility. + + --linear + Use a linear search to find the MSRV + + This method checks toolchain from the most recent release to the earliest. + + --write-toolchain-file + Pin the MSRV by writing the version to a rust-toolchain file + + The toolchain file will pin the Rust version for this crate. See https://rust-lang.github.io/rustup/overrides.html#the-toolchain-file for more. + + --ignore-lockfile + Temporarily remove the lockfile, so it will not interfere with the building process + + This is important when testing against older Rust versions such as Cargo versions prior to Rust 1.38.0, for which Cargo does not recognize the newer lockfile formats. + + --no-read-min-edition + Don't read the `edition` of the crate and do not use its value to reduce the search space + + --no-check-feedback + Don't print the result of compatibility checks + + The feedback of a compatibility check can be useful to determine why a certain Rust version is not compatible. Rust usually prints very detailed error messages. While most often very useful, in some cases they may be too noisy or lengthy. If this flag is given, the result messages will not be printed. + + --write-msrv + Write the MSRV to the Cargo manifest + + For toolchains which include a Cargo version which supports the rust-version field, the `package.rust-version` field will be written. For older Rust toolchains, the `package.metadata.msrv` field will be written instead. + +Rust releases options: + --min + Least recent version or edition to take into account + + Given version must match a valid Rust toolchain, and be semver compatible, be a two component `major.minor` version. or match a Rust edition alias. + + For example, the edition alias "2018" would match Rust version `1.31.0`, since that's the first version which added support for the Rust 2018 edition. + + --max + Most recent version to take into account + + Given version must match a valid Rust toolchain, and be semver compatible, or be a two component `major.minor` version. + + --include-all-patch-releases + Include all patch releases, instead of only the last + + --release-source + [default: rust-changelog] + [possible values: rust-changelog, rust-dist] + +Toolchain options: + --target + Check against a custom target (instead of the rustup default) + +Custom check options: + --path + Path to cargo project directory + + --manifest-path + Path to cargo manifest file + + [CUSTOM_CHECK_COMMAND]... + Supply a custom `check` command to be used by cargo msrv + +User output options: + --output-format + Set the format of user output + + [default: human] + + Possible values: + - human: + Progress bar rendered to stderr + - json: + Json status updates printed to stdout + - minimal: + Minimal output, usually just the result, such as the MSRV or whether verify succeeded or failed + + --no-user-output + Disable user output + +Debug output options: + --no-log + Disable logging + + --log-target + Specify where the program should output its logs + + [default: file] + [possible values: file, stdout] + + --log-level + Specify the severity of logs which should be + + [default: info] + [possible values: trace, debug, info, warn, error] + + + You may provide a custom compatibility `check` command as the last argument (only + when this argument is provided via the double dash syntax, e.g. `$ cargo msrv -- custom + command`. + This custom check command will then be used to validate whether a Rust version is + compatible. + A custom `check` command should be runnable by rustup, as they will be passed on to + rustup like so: `rustup run `. NB: You only need to provide the + part. + + By default, the custom check command is `cargo check`. ``` ### JSON format @@ -215,7 +257,7 @@ is compatible, completes. #### MSRV completed -Reported when all actions for a mode have been run to completion. +Reported when all actions for a mode have been run to completion. ```jsonc { @@ -267,7 +309,7 @@ specific toolchain version, and our multiple tests may attempt to overwrite or m tests to get stuck and fail. You can achieve the above with the following Cargo command: `cargo test -- --test-threads=1`. ### License - + Licensed under either of * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) diff --git a/src/cli.rs b/src/cli.rs index 860ffdc1..546d6c7a 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -9,7 +9,7 @@ use crate::config::ConfigBuilder; use crate::default_target::default_target; use crate::manifest::bare_version::BareVersion; use crate::{CargoMSRVError, Config, SubcommandId}; -use clap::{AppSettings, Args, Parser, Subcommand}; +use clap::{Args, Parser, Subcommand}; use std::convert::{TryFrom, TryInto}; use std::ffi::{OsStr, OsString}; @@ -21,9 +21,9 @@ pub(crate) mod shared_opts; pub(crate) mod toolchain_opts; #[derive(Debug, Parser)] -#[clap(version, bin_name = "cargo", max_term_width = 120)] +#[command(version, bin_name = "cargo", max_term_width = 120)] pub struct CargoCli { - #[clap(subcommand)] + #[command(subcommand)] subcommand: CargoMsrvCli, } @@ -68,18 +68,18 @@ fn modify_args, T: Into + Clone>( #[derive(Debug, Subcommand)] pub(in crate::cli) enum CargoMsrvCli { /// Find your Minimum Supported Rust Version! - #[clap( + #[command( author = "Martijn Gribnau ", after_help = r#" You may provide a custom compatibility `check` command as the last argument (only when this argument is provided via the double dash syntax, e.g. `$ cargo msrv -- custom command`. This custom check command will then be used to validate whether a Rust version is - compatible. + compatible. A custom `check` command should be runnable by rustup, as they will be passed on to rustup like so: `rustup run `. NB: You only need to provide the part. - + By default, the custom check command is `cargo check`. "# )] @@ -87,24 +87,24 @@ pub(in crate::cli) enum CargoMsrvCli { } #[derive(Debug, Args)] -#[clap(version)] +#[command(version)] pub(in crate::cli) struct CargoMsrvOpts { - #[clap(flatten)] + #[command(flatten)] pub(in crate::cli) find_opts: FindOpts, - #[clap(flatten)] + #[command(flatten)] pub(in crate::cli) shared_opts: SharedOpts, - #[clap(subcommand)] + #[command(subcommand)] pub(in crate::cli) subcommand: Option, /// DEPRECATED: Use the `cargo msrv verify` subcommand instead - #[clap(long, global = false, hide = true)] + #[arg(long, global = false, hide = true)] pub(in crate::cli) verify: bool, } #[derive(Debug, Subcommand)] -#[clap(propagate_version = true)] +#[command(propagate_version = true)] pub(in crate::cli) enum SubCommand { /// Display the MSRV's of dependencies List(ListOpts), @@ -118,15 +118,15 @@ pub(in crate::cli) enum SubCommand { } #[derive(Debug, Args)] -#[clap(next_help_heading = "LIST OPTIONS", setting = AppSettings::DeriveDisplayOrder)] +#[command(next_help_heading = "List options")] pub(in crate::cli) struct ListOpts { /// Display the MSRV's of crates that your crate depends on - #[clap(long, possible_values = ListMsrvVariant::variants(), default_value_t)] + #[arg(long, value_enum, default_value_t)] variant: ListMsrvVariant, } #[derive(Debug, Args)] -#[clap(next_help_heading = "SET OPTIONS", setting = AppSettings::DeriveDisplayOrder)] +#[command(next_help_heading = "Set options")] pub(in crate::cli) struct SetOpts { /// The version to be set as MSRV /// @@ -134,29 +134,26 @@ pub(in crate::cli) struct SetOpts { /// MSRV values prior to Rust 1.56 will be written to the `package.metadata.msrv` field /// in the Cargo manifest. MSRV's greater or equal to 1.56 will be written to /// `package.rust-version` in the Cargo manifest. - #[clap(value_name = "MSRV")] + #[arg(value_name = "MSRV")] msrv: BareVersion, } #[derive(Debug, Args)] -#[clap( - next_help_heading = "VERIFY OPTIONS", - setting = AppSettings::DeriveDisplayOrder, -)] +#[command(next_help_heading = "Verify options")] pub(in crate::cli) struct VerifyOpts { - #[clap(flatten)] + #[command(flatten)] pub(in crate::cli) rust_releases_opts: RustReleasesOpts, - #[clap(flatten)] + #[command(flatten)] pub(in crate::cli) toolchain_opts: ToolchainOpts, - #[clap(flatten)] + #[command(flatten)] pub(in crate::cli) custom_check: CustomCheckOpts, /// The Rust version, to check against for toolchain compatibility /// /// If not set, the MSRV will be parsed from the Cargo manifest instead. - #[clap(long, value_name = "rust-version")] + #[arg(long, value_name = "rust-version")] rust_version: Option, } @@ -227,3 +224,14 @@ fn make_mode(opts: &CargoMsrvOpts) -> SubcommandId { } }) } + +#[cfg(test)] +mod tests { + use super::CargoCli; + + #[test] + fn verify_cli() { + use clap::CommandFactory; + CargoCli::command().debug_assert(); + } +} diff --git a/src/cli/custom_check_opts.rs b/src/cli/custom_check_opts.rs index ab385199..84aec19b 100644 --- a/src/cli/custom_check_opts.rs +++ b/src/cli/custom_check_opts.rs @@ -1,10 +1,9 @@ -use clap::AppSettings; use clap::Args; #[derive(Debug, Args)] -#[clap(next_help_heading = "CUSTOM CHECK OPTIONS", setting = AppSettings::DeriveDisplayOrder)] +#[command(next_help_heading = "Custom check options")] pub struct CustomCheckOpts { /// Supply a custom `check` command to be used by cargo msrv - #[clap(last = true, required = false)] + #[arg(last = true, required = false)] pub custom_check_command: Vec, } diff --git a/src/cli/find_opts.rs b/src/cli/find_opts.rs index c3ae3009..22654015 100644 --- a/src/cli/find_opts.rs +++ b/src/cli/find_opts.rs @@ -1,43 +1,42 @@ use crate::cli::custom_check_opts::CustomCheckOpts; use crate::cli::rust_releases_opts::RustReleasesOpts; use crate::cli::toolchain_opts::ToolchainOpts; -use clap::AppSettings; use clap::Args; // Cli Options for top-level cargo-msrv (find) command #[derive(Debug, Args)] -#[clap(next_help_heading = "FIND MSRV OPTIONS", setting = AppSettings::DeriveDisplayOrder)] +#[command(next_help_heading = "Find MSRV options")] pub struct FindOpts { /// Use a binary search to find the MSRV (default) /// /// When the search space is sufficiently large, which is common, this is much /// faster than a linear search. A binary search will approximately halve the search /// space for each Rust version checked for compatibility. - #[clap(long, conflicts_with = "linear")] + #[arg(long, conflicts_with = "linear")] pub bisect: bool, /// Use a linear search to find the MSRV /// /// This method checks toolchain from the most recent release to the earliest. - #[clap(long, conflicts_with = "bisect")] + #[arg(long, conflicts_with = "bisect")] pub linear: bool, /// Pin the MSRV by writing the version to a rust-toolchain file /// /// The toolchain file will pin the Rust version for this crate. /// See https://rust-lang.github.io/rustup/overrides.html#the-toolchain-file for more. - #[clap(long, alias = "toolchain-file")] + #[arg(long, alias = "toolchain-file")] pub write_toolchain_file: bool, /// Temporarily remove the lockfile, so it will not interfere with the building process /// /// This is important when testing against older Rust versions such as Cargo versions prior to /// Rust 1.38.0, for which Cargo does not recognize the newer lockfile formats. - #[clap(long)] + #[arg(long)] pub ignore_lockfile: bool, /// Don't read the `edition` of the crate and do not use its value to reduce the search space - #[clap(long)] + #[arg(long)] pub no_read_min_edition: bool, /// Don't print the result of compatibility checks @@ -46,7 +45,7 @@ pub struct FindOpts { /// version is not compatible. Rust usually prints very detailed error messages. /// While most often very useful, in some cases they may be too noisy or lengthy. /// If this flag is given, the result messages will not be printed. - #[clap(long)] + #[arg(long)] pub no_check_feedback: bool, /// Write the MSRV to the Cargo manifest @@ -54,15 +53,15 @@ pub struct FindOpts { /// For toolchains which include a Cargo version which supports the rust-version field, /// the `package.rust-version` field will be written. For older Rust toolchains, /// the `package.metadata.msrv` field will be written instead. - #[clap(long)] + #[arg(long)] pub write_msrv: bool, - #[clap(flatten)] + #[command(flatten)] pub rust_releases_opts: RustReleasesOpts, - #[clap(flatten)] + #[command(flatten)] pub toolchain_opts: ToolchainOpts, - #[clap(flatten)] + #[command(flatten)] pub custom_check_opts: CustomCheckOpts, } diff --git a/src/cli/rust_releases_opts.rs b/src/cli/rust_releases_opts.rs index b266acbb..ae97171f 100644 --- a/src/cli/rust_releases_opts.rs +++ b/src/cli/rust_releases_opts.rs @@ -1,12 +1,11 @@ use crate::manifest::bare_version; use crate::manifest::bare_version::BareVersion; use crate::ReleaseSource; -use clap::AppSettings; use clap::Args; use std::str::FromStr; #[derive(Debug, Args)] -#[clap(next_help_heading = "RUST RELEASES OPTIONS", setting = AppSettings::DeriveDisplayOrder)] +#[command(next_help_heading = "Rust releases options")] pub struct RustReleasesOpts { /// Least recent version or edition to take into account /// @@ -15,25 +14,25 @@ pub struct RustReleasesOpts { /// /// For example, the edition alias "2018" would match Rust version `1.31.0`, since that's the /// first version which added support for the Rust 2018 edition. - #[clap(long, value_name = "VERSION_SPEC or EDITION", alias = "minimum")] + #[arg(long, value_name = "VERSION_SPEC or EDITION", alias = "minimum")] pub min: Option, /// Most recent version to take into account /// /// Given version must match a valid Rust toolchain, and be semver compatible, or /// be a two component `major.minor` version. - #[clap(long, value_name = "VERSION_SPEC", alias = "maximum")] + #[arg(long, value_name = "VERSION_SPEC", alias = "maximum")] pub max: Option, /// Include all patch releases, instead of only the last - #[clap(long)] + #[arg(long)] pub include_all_patch_releases: bool, - #[clap(long, possible_values = ReleaseSource::variants(), default_value_t, value_name = "SOURCE")] + #[arg(long, value_enum, default_value_t, value_name = "SOURCE")] pub release_source: ReleaseSource, } -#[derive(Debug)] +#[derive(Clone, Debug)] pub enum EditionOrVersion { Edition(Edition), Version(BareVersion), diff --git a/src/cli/shared_opts.rs b/src/cli/shared_opts.rs index 522edce2..04426c9c 100644 --- a/src/cli/shared_opts.rs +++ b/src/cli/shared_opts.rs @@ -1,59 +1,57 @@ use crate::config::{OutputFormat, TracingTargetOption}; use crate::log_level::LogLevel; -use clap::AppSettings; -use clap::ArgGroup; -use clap::Args; +use clap::{ArgGroup, Args, ValueHint}; use std::path::PathBuf; // Cli Options shared between subcommands #[derive(Debug, Args)] -#[clap(setting = AppSettings::DeriveDisplayOrder)] -#[clap(group(ArgGroup::new("paths").args(&["path", "manifest-path"])))] +#[command(group(ArgGroup::new("paths").args(&["path", "manifest_path"])))] pub struct SharedOpts { /// Path to cargo project directory - #[clap(long, value_name = "Crate Directory", global = true)] + #[arg(long, value_name = "Crate Directory", global = true, value_hint = ValueHint::DirPath)] pub path: Option, /// Path to cargo manifest file - #[clap(long, value_name = "Cargo Manifest", global = true)] + #[arg(long, value_name = "Cargo Manifest", global = true, value_hint = ValueHint::FilePath)] pub manifest_path: Option, - #[clap(flatten)] + #[command(flatten)] pub user_output_opts: UserOutputOpts, - #[clap(flatten)] + #[command(flatten)] pub debug_output_opts: DebugOutputOpts, } #[derive(Debug, Args)] -#[clap(next_help_heading = "USER OUTPUT OPTIONS", setting = AppSettings::DeriveDisplayOrder)] +#[command(next_help_heading = "User output options")] pub struct UserOutputOpts { /// Set the format of user output - #[clap(long, - possible_values = OutputFormat::custom_formats(), + #[arg( + long, + value_enum, default_value_t, value_name = "FORMAT", - global = true, + global = true )] pub output_format: OutputFormat, /// Disable user output - #[clap(long, global = true)] + #[arg(long, global = true)] pub no_user_output: bool, } #[derive(Debug, Args)] -#[clap(next_help_heading = "DEBUG OUTPUT OPTIONS", setting = AppSettings::DeriveDisplayOrder)] +#[command(next_help_heading = "Debug output options")] pub struct DebugOutputOpts { /// Disable logging - #[clap(long, global = true)] + #[arg(long, global = true)] pub no_log: bool, /// Specify where the program should output its logs - #[clap( + #[arg( long, - arg_enum, + value_enum, default_value_t, value_name = "LOG TARGET", global = true @@ -61,6 +59,6 @@ pub struct DebugOutputOpts { pub log_target: TracingTargetOption, /// Specify the severity of logs which should be - #[clap(long, default_value_t, value_name = "LEVEL", global = true)] + #[arg(long, value_enum, default_value_t, value_name = "LEVEL", global = true)] pub log_level: LogLevel, } diff --git a/src/cli/toolchain_opts.rs b/src/cli/toolchain_opts.rs index 92cb4396..733bd3a8 100644 --- a/src/cli/toolchain_opts.rs +++ b/src/cli/toolchain_opts.rs @@ -1,12 +1,11 @@ -use clap::AppSettings; use clap::Args; // Cli Options for commands which invoke Rust toolchains, such as the top level cargo msrv command // (find) or cargo msrv verify #[derive(Debug, Args)] -#[clap(next_help_heading = "TOOLCHAIN OPTIONS", setting = AppSettings::DeriveDisplayOrder)] +#[command(next_help_heading = "Toolchain options")] pub struct ToolchainOpts { /// Check against a custom target (instead of the rustup default) - #[clap(long, value_name = "TARGET")] + #[arg(long, value_name = "TARGET")] pub target: Option, } diff --git a/src/config.rs b/src/config.rs index fbcf68e5..a2fd9c27 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,4 +1,4 @@ -use clap::ArgEnum; +use clap::ValueEnum; use std::convert::{TryFrom, TryInto}; use std::fmt; use std::path::{Path, PathBuf}; @@ -19,24 +19,20 @@ pub(crate) mod list; pub(crate) mod set; pub(crate) mod verify; -#[derive(Debug, Clone, Copy)] +#[derive(Clone, Copy, Debug, Default, ValueEnum)] pub enum OutputFormat { /// Progress bar rendered to stderr + #[default] Human, /// Json status updates printed to stdout Json, /// Minimal output, usually just the result, such as the MSRV or whether verify succeeded or failed Minimal, /// No output -- meant to be used for debugging and testing + #[value(skip)] None, } -impl Default for OutputFormat { - fn default() -> Self { - Self::Human - } -} - impl fmt::Display for OutputFormat { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { @@ -64,18 +60,6 @@ impl FromStr for OutputFormat { } } -impl OutputFormat { - pub const HUMAN: &'static str = "human"; - pub const JSON: &'static str = "json"; - pub const MINIMAL: &'static str = "minimal"; - - /// A set of formats which may be given as a configuration option - /// through the CLI. - pub fn custom_formats() -> &'static [&'static str] { - &[Self::HUMAN, Self::JSON, Self::MINIMAL] - } -} - /// Gets a [`Config`] from the given matches, but sets output_format to None /// /// This is meant to be used for testing @@ -112,30 +96,15 @@ impl From for &'static str { } } -#[derive(Debug, Clone, Copy, Eq, PartialEq, serde::Serialize)] +#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, serde::Serialize, ValueEnum)] #[serde(rename_all = "snake_case")] pub enum ReleaseSource { + #[default] RustChangelog, #[cfg(feature = "rust-releases-dist-source")] RustDist, } -impl Default for ReleaseSource { - fn default() -> Self { - Self::RustChangelog - } -} - -impl ReleaseSource { - pub(crate) fn variants() -> &'static [&'static str] { - &[ - "rust-changelog", - #[cfg(feature = "rust-releases-dist-source")] - "rust-dist", - ] - } -} - impl FromStr for ReleaseSource { type Err = CargoMSRVError; @@ -519,7 +488,7 @@ impl TracingOptions { } } -#[derive(Debug, Copy, Clone, ArgEnum)] +#[derive(Debug, Copy, Clone, ValueEnum)] pub enum TracingTargetOption { File, Stdout, diff --git a/src/config/list.rs b/src/config/list.rs index 8db6ce3f..c891b5ab 100644 --- a/src/config/list.rs +++ b/src/config/list.rs @@ -1,14 +1,17 @@ use std::fmt::Formatter; use std::{fmt, str::FromStr}; +use clap::ValueEnum; + #[derive(Clone, Debug)] pub struct ListCmdConfig { pub variant: ListMsrvVariant, } -#[derive(Copy, Clone, Debug, Eq, PartialEq)] +#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, ValueEnum)] pub enum ListMsrvVariant { DirectDeps, + #[default] OrderedByMSRV, } @@ -40,15 +43,3 @@ impl fmt::Display for ListMsrvVariant { } } } - -impl ListMsrvVariant { - pub(crate) const fn variants() -> &'static [&'static str] { - &[DIRECT_DEPS, ORDERED_BY_MSRV] - } -} - -impl Default for ListMsrvVariant { - fn default() -> Self { - Self::OrderedByMSRV - } -} diff --git a/src/log_level.rs b/src/log_level.rs index 6f2d61fd..4aa545da 100644 --- a/src/log_level.rs +++ b/src/log_level.rs @@ -1,10 +1,13 @@ use std::fmt::{Display, Formatter}; use std::str::FromStr; -#[derive(Debug, Copy, Clone, Eq, PartialEq)] +use clap::ValueEnum; + +#[derive(Copy, Clone, Debug, Default, Eq, PartialEq, ValueEnum)] pub enum LogLevel { Trace, Debug, + #[default] Info, Warn, Error, @@ -16,12 +19,6 @@ impl LogLevel { } } -impl Default for LogLevel { - fn default() -> Self { - Self::Info - } -} - impl Display for LogLevel { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { f.write_fmt(format_args!("{:?}", self))