From 65cc99353d6e8676b19e1d7592919c8f53d81f70 Mon Sep 17 00:00:00 2001 From: Martijn Gribnau Date: Tue, 14 Nov 2023 22:56:33 +0100 Subject: [PATCH 1/6] refactor: Rename CustomCheckOpts to CargoCheckOpts --- src/cli.rs | 4 ++-- src/cli/custom_check_opts.rs | 2 +- src/cli/find_opts.rs | 4 ++-- src/context.rs | 6 +++--- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/cli.rs b/src/cli.rs index 3e0efda3..23ff8940 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -1,4 +1,4 @@ -use crate::cli::custom_check_opts::CustomCheckOpts; +use crate::cli::custom_check_opts::CargoCheckOpts; use crate::cli::find_opts::FindOpts; use crate::cli::rust_releases_opts::RustReleasesOpts; use crate::cli::shared_opts::SharedOpts; @@ -150,7 +150,7 @@ pub struct VerifyOpts { pub toolchain_opts: ToolchainOpts, #[command(flatten)] - pub custom_check: CustomCheckOpts, + pub cargo_check_opts: CargoCheckOpts, /// The Rust version, to check against for toolchain compatibility /// diff --git a/src/cli/custom_check_opts.rs b/src/cli/custom_check_opts.rs index 1f8026b5..b643656b 100644 --- a/src/cli/custom_check_opts.rs +++ b/src/cli/custom_check_opts.rs @@ -2,7 +2,7 @@ use clap::Args; #[derive(Debug, Args)] #[command(next_help_heading = "Custom check options")] -pub struct CustomCheckOpts { +pub struct CargoCheckOpts { /// Supply a custom `check` command to be used by cargo msrv #[arg(last = true)] pub custom_check_command: Option>, diff --git a/src/cli/find_opts.rs b/src/cli/find_opts.rs index 854a54de..5844dc47 100644 --- a/src/cli/find_opts.rs +++ b/src/cli/find_opts.rs @@ -1,4 +1,4 @@ -use crate::cli::custom_check_opts::CustomCheckOpts; +use crate::cli::custom_check_opts::CargoCheckOpts; use crate::cli::rust_releases_opts::RustReleasesOpts; use crate::cli::toolchain_opts::ToolchainOpts; use clap::Args; @@ -59,5 +59,5 @@ pub struct FindOpts { pub toolchain_opts: ToolchainOpts, #[command(flatten)] - pub custom_check_opts: CustomCheckOpts, + pub custom_check_opts: CargoCheckOpts, } diff --git a/src/context.rs b/src/context.rs index 09ca8b21..0173a8e8 100644 --- a/src/context.rs +++ b/src/context.rs @@ -25,7 +25,7 @@ pub mod set; pub mod show; pub mod verify; -use crate::cli::custom_check_opts::CustomCheckOpts; +use crate::cli::custom_check_opts::CargoCheckOpts; use crate::cli::rust_releases_opts::Edition; use crate::cli::{CargoMsrvOpts, SubCommand}; use crate::default_target::default_target; @@ -196,8 +196,8 @@ pub struct CheckCmdContext { pub rustup_command: Option>, } -impl From for CheckCmdContext { - fn from(opts: CustomCheckOpts) -> Self { +impl From for CheckCmdContext { + fn from(opts: CargoCheckOpts) -> Self { Self { rustup_command: opts.custom_check_command, } From 45cb58a9e56a5f5a69e6d7bb04959611f9bf689c Mon Sep 17 00:00:00 2001 From: Martijn Gribnau Date: Tue, 14 Nov 2023 22:57:56 +0100 Subject: [PATCH 2/6] refactor: Rename CheckCmdContext to CargoCheckContext --- src/context.rs | 4 ++-- src/context/find.rs | 4 ++-- src/context/verify.rs | 4 ++-- src/sub_command/find/tests.rs | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/context.rs b/src/context.rs index 0173a8e8..d174cbd1 100644 --- a/src/context.rs +++ b/src/context.rs @@ -191,12 +191,12 @@ impl TryFrom for ToolchainContext { } #[derive(Debug)] -pub struct CheckCmdContext { +pub struct CargoCheckContext { /// The custom `Rustup` command to invoke for a toolchain. pub rustup_command: Option>, } -impl From for CheckCmdContext { +impl From for CargoCheckContext { fn from(opts: CargoCheckOpts) -> Self { Self { rustup_command: opts.custom_check_command, diff --git a/src/context/find.rs b/src/context/find.rs index 99968744..2eab4b0a 100644 --- a/src/context/find.rs +++ b/src/context/find.rs @@ -1,7 +1,7 @@ use crate::check::RunCommand; use crate::cli::CargoMsrvOpts; use crate::context::{ - CheckCmdContext, EnvironmentContext, RustReleasesContext, SearchMethod, ToolchainContext, + CargoCheckContext, EnvironmentContext, RustReleasesContext, SearchMethod, ToolchainContext, UserOutputContext, }; use crate::error::CargoMSRVError; @@ -31,7 +31,7 @@ pub struct FindContext { pub toolchain: ToolchainContext, /// The context for checks to be used with rustup - pub check_cmd: CheckCmdContext, + pub check_cmd: CargoCheckContext, /// Resolved environment options pub environment: EnvironmentContext, diff --git a/src/context/verify.rs b/src/context/verify.rs index ac4a3013..e9973a9d 100644 --- a/src/context/verify.rs +++ b/src/context/verify.rs @@ -1,6 +1,6 @@ use crate::cli::{CargoMsrvOpts, SubCommand}; use crate::context::{ - CheckCmdContext, EnvironmentContext, RustReleasesContext, ToolchainContext, UserOutputContext, + CargoCheckContext, EnvironmentContext, RustReleasesContext, ToolchainContext, UserOutputContext, }; use crate::check::RunCommand; @@ -26,7 +26,7 @@ pub struct VerifyContext { pub toolchain: ToolchainContext, /// The context for custom checks to be used with rustup - pub check_cmd: CheckCmdContext, + pub check_cmd: CargoCheckContext, /// Resolved environment options pub environment: EnvironmentContext, diff --git a/src/sub_command/find/tests.rs b/src/sub_command/find/tests.rs index 519ebadf..08a384cf 100644 --- a/src/sub_command/find/tests.rs +++ b/src/sub_command/find/tests.rs @@ -1,7 +1,7 @@ use super::*; use crate::check::TestRunner; use crate::context::{ - CheckCmdContext, EnvironmentContext, ReleaseSource, RustReleasesContext, ToolchainContext, + CargoCheckContext, EnvironmentContext, ReleaseSource, RustReleasesContext, ToolchainContext, UserOutputContext, }; use crate::manifest::bare_version::BareVersion; @@ -247,7 +247,7 @@ fn create_test_context() -> FindContext { toolchain: ToolchainContext { target: "x".to_string(), }, - check_cmd: CheckCmdContext { + check_cmd: CargoCheckContext { rustup_command: None, }, environment: EnvironmentContext { From 96423491cb4e4ec479c0292781b8b1cc2284172a Mon Sep 17 00:00:00 2001 From: Martijn Gribnau Date: Wed, 15 Nov 2023 00:02:22 +0100 Subject: [PATCH 3/6] feat: Add cargo's features flags to cli and context --- src/cli/custom_check_opts.rs | 9 +++++++++ src/context.rs | 9 +++++++++ src/sub_command/find/tests.rs | 3 +++ 3 files changed, 21 insertions(+) diff --git a/src/cli/custom_check_opts.rs b/src/cli/custom_check_opts.rs index b643656b..36d91759 100644 --- a/src/cli/custom_check_opts.rs +++ b/src/cli/custom_check_opts.rs @@ -3,6 +3,15 @@ use clap::Args; #[derive(Debug, Args)] #[command(next_help_heading = "Custom check options")] pub struct CargoCheckOpts { + #[arg(long)] + pub features: Option>, + + #[arg(long, value_delimiter = ' ')] + pub all_features: bool, + + #[arg(long)] + pub no_default_features: bool, + /// Supply a custom `check` command to be used by cargo msrv #[arg(last = true)] pub custom_check_command: Option>, diff --git a/src/context.rs b/src/context.rs index d174cbd1..f38ac554 100644 --- a/src/context.rs +++ b/src/context.rs @@ -192,6 +192,12 @@ impl TryFrom for ToolchainContext { #[derive(Debug)] pub struct CargoCheckContext { + pub cargo_features: Option>, + + pub cargo_all_features: bool, + + pub cargo_no_default_features: bool, + /// The custom `Rustup` command to invoke for a toolchain. pub rustup_command: Option>, } @@ -199,6 +205,9 @@ pub struct CargoCheckContext { impl From for CargoCheckContext { fn from(opts: CargoCheckOpts) -> Self { Self { + cargo_features: opts.features, + cargo_all_features: opts.all_features, + cargo_no_default_features: opts.no_default_features, rustup_command: opts.custom_check_command, } } diff --git a/src/sub_command/find/tests.rs b/src/sub_command/find/tests.rs index 08a384cf..d13c6ec0 100644 --- a/src/sub_command/find/tests.rs +++ b/src/sub_command/find/tests.rs @@ -248,6 +248,9 @@ fn create_test_context() -> FindContext { target: "x".to_string(), }, check_cmd: CargoCheckContext { + cargo_features: None, + cargo_all_features: false, + cargo_no_default_features: false, rustup_command: None, }, environment: EnvironmentContext { From eb2e597da5a997d50c88c1c798f252af45ad6b86 Mon Sep 17 00:00:00 2001 From: Martijn Gribnau Date: Wed, 15 Nov 2023 00:04:14 +0100 Subject: [PATCH 4/6] refactor: Rename module command to rustup_command --- src/check/rustup_toolchain_check.rs | 2 +- src/default_target.rs | 2 +- src/download.rs | 2 +- src/lib.rs | 2 +- src/{command.rs => rustup_command.rs} | 0 5 files changed, 4 insertions(+), 4 deletions(-) rename src/{command.rs => rustup_command.rs} (100%) diff --git a/src/check/rustup_toolchain_check.rs b/src/check/rustup_toolchain_check.rs index e28a0b97..afb8a5cb 100644 --- a/src/check/rustup_toolchain_check.rs +++ b/src/check/rustup_toolchain_check.rs @@ -1,10 +1,10 @@ use crate::check::Check; -use crate::command::RustupCommand; use crate::context::EnvironmentContext; use crate::download::{DownloadToolchain, ToolchainDownloader}; use crate::error::{IoError, IoErrorSource}; use crate::lockfile::LockfileHandler; use crate::reporter::event::{CheckMethod, CheckResult, CheckToolchain, Method}; +use crate::rustup_command::RustupCommand; use crate::toolchain::ToolchainSpec; use crate::{lockfile, CargoMSRVError, Outcome, Reporter, TResult}; use camino::{Utf8Path, Utf8PathBuf}; diff --git a/src/default_target.rs b/src/default_target.rs index 6f4863f6..b12e5565 100644 --- a/src/default_target.rs +++ b/src/default_target.rs @@ -1,5 +1,5 @@ -use crate::command::RustupCommand; use crate::error::{CargoMSRVError, TResult}; +use crate::rustup_command::RustupCommand; /// Uses the `.rustup/settings.toml` file to determine the default target (aka the /// `default_host_triple`) if not set by a user. diff --git a/src/download.rs b/src/download.rs index 96c26a9a..1b58b981 100644 --- a/src/download.rs +++ b/src/download.rs @@ -1,6 +1,6 @@ -use crate::command::RustupCommand; use crate::error::RustupInstallFailed; use crate::reporter::event::SetupToolchain; +use crate::rustup_command::RustupCommand; use crate::toolchain::ToolchainSpec; use crate::{CargoMSRVError, Reporter, TResult}; diff --git a/src/lib.rs b/src/lib.rs index 591eac54..d2412254 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -39,7 +39,6 @@ pub mod reporter; pub mod toolchain; pub(crate) mod combinators; -pub(crate) mod command; mod context; pub(crate) mod default_target; pub(crate) mod dependency_graph; @@ -53,6 +52,7 @@ pub(crate) mod outcome; mod release_index; pub(crate) mod releases_filter; mod rust_release; +pub(crate) mod rustup_command; pub(crate) mod search_method; pub(crate) mod sub_command; pub(crate) mod typed_bool; diff --git a/src/command.rs b/src/rustup_command.rs similarity index 100% rename from src/command.rs rename to src/rustup_command.rs From 728f5d4c9c944f8d0e3953589fc791177b5de4bf Mon Sep 17 00:00:00 2001 From: Martijn Gribnau Date: Wed, 15 Nov 2023 02:20:46 +0100 Subject: [PATCH 5/6] feat: Add CargoCommand with features and target options * Adds CargoCommand struct * Unlike RustupCommand, not (yet) intended to run standalone, since we use rustup to run certain versions of toolchains * Currently only used for "cargo check", but could be refactored to also include the likes of "cargo build" and friends (cargo build support could help for adding support for Rust < 1.16). * Has options to forward features and target to cargo --- src/check/rustup_toolchain_check.rs | 16 +- src/cli.rs | 4 +- src/cli/custom_check_opts.rs | 14 +- src/cli/find_opts.rs | 4 +- src/command.rs | 2 + src/command/cargo_command.rs | 166 ++++++++++++++++++ src/{ => command}/rustup_command.rs | 0 src/context.rs | 8 +- src/context/find.rs | 13 +- src/context/verify.rs | 14 +- src/default_target.rs | 2 +- src/download.rs | 2 +- src/lib.rs | 4 +- src/sub_command/find/tests.rs | 4 +- tests/find_msrv.rs | 97 ++++++++++ .../cargo-feature-required/.gitignore | 3 + .../cargo-feature-required/Cargo.toml | 7 + .../cargo-feature-required/src/lib.rs | 10 ++ .../cargo-feature-requires-none/.gitignore | 3 + .../cargo-feature-requires-none/Cargo.toml | 8 + .../cargo-feature-requires-none/src/lib.rs | 11 ++ 21 files changed, 362 insertions(+), 30 deletions(-) create mode 100644 src/command.rs create mode 100644 src/command/cargo_command.rs rename src/{ => command}/rustup_command.rs (100%) create mode 100644 tests/fixtures/cargo-feature-required/.gitignore create mode 100644 tests/fixtures/cargo-feature-required/Cargo.toml create mode 100644 tests/fixtures/cargo-feature-required/src/lib.rs create mode 100644 tests/fixtures/cargo-feature-requires-none/.gitignore create mode 100644 tests/fixtures/cargo-feature-requires-none/Cargo.toml create mode 100644 tests/fixtures/cargo-feature-requires-none/src/lib.rs diff --git a/src/check/rustup_toolchain_check.rs b/src/check/rustup_toolchain_check.rs index afb8a5cb..dc87fe2d 100644 --- a/src/check/rustup_toolchain_check.rs +++ b/src/check/rustup_toolchain_check.rs @@ -1,10 +1,11 @@ use crate::check::Check; +use crate::command::cargo_command::CargoCommand; +use crate::command::rustup_command::RustupCommand; use crate::context::EnvironmentContext; use crate::download::{DownloadToolchain, ToolchainDownloader}; use crate::error::{IoError, IoErrorSource}; use crate::lockfile::LockfileHandler; use crate::reporter::event::{CheckMethod, CheckResult, CheckToolchain, Method}; -use crate::rustup_command::RustupCommand; use crate::toolchain::ToolchainSpec; use crate::{lockfile, CargoMSRVError, Outcome, Reporter, TResult}; use camino::{Utf8Path, Utf8PathBuf}; @@ -214,15 +215,10 @@ pub struct RunCommand { } impl RunCommand { - pub fn default(target: impl ToString) -> Self { - let command = vec![ - "cargo".to_string(), - "check".to_string(), - "--target".to_string(), - target.to_string(), - ]; - - Self { command } + pub fn default(cargo_command: CargoCommand) -> Self { + Self { + command: cargo_command.into_args(), + } } pub fn custom(command: Vec) -> Self { diff --git a/src/cli.rs b/src/cli.rs index 23ff8940..88f83b4f 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -1,4 +1,4 @@ -use crate::cli::custom_check_opts::CargoCheckOpts; +use crate::cli::custom_check_opts::CheckCommandOpts; use crate::cli::find_opts::FindOpts; use crate::cli::rust_releases_opts::RustReleasesOpts; use crate::cli::shared_opts::SharedOpts; @@ -150,7 +150,7 @@ pub struct VerifyOpts { pub toolchain_opts: ToolchainOpts, #[command(flatten)] - pub cargo_check_opts: CargoCheckOpts, + pub cargo_check_opts: CheckCommandOpts, /// The Rust version, to check against for toolchain compatibility /// diff --git a/src/cli/custom_check_opts.rs b/src/cli/custom_check_opts.rs index 36d91759..e6dbe264 100644 --- a/src/cli/custom_check_opts.rs +++ b/src/cli/custom_check_opts.rs @@ -2,13 +2,25 @@ use clap::Args; #[derive(Debug, Args)] #[command(next_help_heading = "Custom check options")] -pub struct CargoCheckOpts { +pub struct CheckCommandOpts { + /// Forwards the provided features to cargo, when running cargo-msrv with the default compatibility + /// check command. + /// + /// If a custom a custom compatibility check command is used, this option is ignored. #[arg(long)] pub features: Option>, + /// Forwards the --all-features flag to cargo, when running cargo-msrv with the default compatibility + /// check command. + /// + /// If a custom a custom compatibility check command is used, this option is ignored. #[arg(long, value_delimiter = ' ')] pub all_features: bool, + /// Forwards the --no-default-features flag to cargo, when running cargo-msrv with the default compatibility + /// check command. + /// + /// If a custom a custom compatibility check command is used, this option is ignored. #[arg(long)] pub no_default_features: bool, diff --git a/src/cli/find_opts.rs b/src/cli/find_opts.rs index 5844dc47..1a949467 100644 --- a/src/cli/find_opts.rs +++ b/src/cli/find_opts.rs @@ -1,4 +1,4 @@ -use crate::cli::custom_check_opts::CargoCheckOpts; +use crate::cli::custom_check_opts::CheckCommandOpts; use crate::cli::rust_releases_opts::RustReleasesOpts; use crate::cli::toolchain_opts::ToolchainOpts; use clap::Args; @@ -59,5 +59,5 @@ pub struct FindOpts { pub toolchain_opts: ToolchainOpts, #[command(flatten)] - pub custom_check_opts: CargoCheckOpts, + pub custom_check_opts: CheckCommandOpts, } diff --git a/src/command.rs b/src/command.rs new file mode 100644 index 00000000..1008efb5 --- /dev/null +++ b/src/command.rs @@ -0,0 +1,2 @@ +pub mod cargo_command; +pub mod rustup_command; diff --git a/src/command/cargo_command.rs b/src/command/cargo_command.rs new file mode 100644 index 00000000..226460db --- /dev/null +++ b/src/command/cargo_command.rs @@ -0,0 +1,166 @@ +#[derive(Debug, Default)] +pub struct CargoCommand { + features: Option>, + all_features: bool, + no_default_features: bool, + target: Option, +} + +impl CargoCommand { + /// Set the features to be forwarded as `cargo --features` + pub fn features(mut self, features: Option>) -> Self { + self.features = features; + self + } + + /// Set the `all features` flag to be forwarded as `cargo --all-features` + pub fn all_features(mut self, value: bool) -> Self { + self.all_features = value; + self + } + + /// Set the `no default features` flag to be forwarded as `cargo --no-default-features` + pub fn no_default_features(mut self, value: bool) -> Self { + self.no_default_features = value; + self + } + + /// Set the target flag to be forwarded as `cargo --target + pub fn target(mut self, target: Option) -> Self { + self.target = target.map(|t| t.to_string()); + self + } + + /// Intended to be used in conjunction with [`RunCommand`] and/or [`RustupCommand`]. + /// + /// [`RunCommand`]: crate::check::RunCommand + /// [`RustupCommand`]: crate::command::rustup_command::RustupCommand + // Currently we don't invoke it from here directly, but we might eventually, if + // we want to also provide some nicer structs around parsing. However compared to + // some other cargo subcommand crates, we also (currently) need rustup, so the invocation + // would need to supply everything we supply to rustup. + pub fn into_args(self) -> Vec { + // Eventually we should also add support for CARGO env var + let mut args = Vec::::with_capacity(8); + + // Currently only `cargo check` is used by cargo msrv. + // Alternatives can be set when using cargo msrv -- custom cmd + // This value does open the path to use cargo build for Rust < 1.16 + args.extend_from_slice(&["cargo".to_string(), "check".to_string()]); + + if let Some(features) = self.features { + let features = features.join(","); + + args.extend_from_slice(&["--features".to_string(), features]); + } + + // probably unnecessary to supply both this and --features, if both have a value, but + // by adding both to the command separately, we can optimally invoke cargo's own behaviour + if self.all_features { + args.push("--all-features".to_string()); + } + + if self.no_default_features { + args.push("--no-default-features".to_string()); + } + + if let Some(target) = self.target { + args.push("--target".to_string()); + args.push(target); + } + + args + } +} + +#[cfg(test)] +mod tests { + use crate::command::cargo_command::CargoCommand; + + #[test] + fn set_features_none() { + let cargo_command = CargoCommand::default(); + let cargo_command = cargo_command.features(None); + assert_eq!( + cargo_command.into_args().join(" "), + "cargo check".to_string() + ); + } + + #[test] + fn set_features_one() { + let cargo_command = CargoCommand::default(); + let cargo_command = cargo_command.features(Some(vec!["pika".to_string()])); + assert_eq!( + cargo_command.into_args().join(" "), + "cargo check --features pika".to_string() + ); + } + + #[test] + fn set_features_two() { + let cargo_command = CargoCommand::default(); + let cargo_command = + cargo_command.features(Some(vec!["chu".to_string(), "chris".to_string()])); + assert_eq!( + cargo_command.into_args().join(" "), + "cargo check --features chu,chris".to_string() + ); + } + + #[test] + fn set_no_default_features() { + let cargo_command = CargoCommand::default(); + let cargo_command = cargo_command.no_default_features(true); + assert_eq!( + cargo_command.into_args().join(" "), + "cargo check --no-default-features".to_string() + ); + } + + #[test] + fn set_all_features() { + let cargo_command = CargoCommand::default(); + let cargo_command = cargo_command.all_features(true); + assert_eq!( + cargo_command.into_args().join(" "), + "cargo check --all-features".to_string() + ); + } + + #[test] + fn set_target_none() { + let cargo_command = CargoCommand::default(); + let cargo_command = cargo_command.target(None::); + assert_eq!( + cargo_command.into_args().join(" "), + "cargo check".to_string() + ); + } + + #[test] + fn set_target_some() { + let cargo_command = CargoCommand::default(); + let cargo_command = cargo_command.target(Some("some")); + assert_eq!( + cargo_command.into_args().join(" "), + "cargo check --target some".to_string() + ); + } + + #[test] + fn combination_of_everything() { + let cargo_command = CargoCommand::default(); + let cargo_command = cargo_command + .features(Some(vec!["pika".to_string(), "chu".to_string()])) + .all_features(true) + .no_default_features(true) + .target(Some("pickme")); + + let cmd = cargo_command.into_args().join(" "); + assert!(cmd.contains("--all-features")); + assert!(cmd.contains("--features pika,chu")); + assert!(cmd.contains("--no-default-features")); + assert!(cmd.contains("--target pickme")); + } +} diff --git a/src/rustup_command.rs b/src/command/rustup_command.rs similarity index 100% rename from src/rustup_command.rs rename to src/command/rustup_command.rs diff --git a/src/context.rs b/src/context.rs index f38ac554..809c42bc 100644 --- a/src/context.rs +++ b/src/context.rs @@ -25,7 +25,7 @@ pub mod set; pub mod show; pub mod verify; -use crate::cli::custom_check_opts::CargoCheckOpts; +use crate::cli::custom_check_opts::CheckCommandOpts; use crate::cli::rust_releases_opts::Edition; use crate::cli::{CargoMsrvOpts, SubCommand}; use crate::default_target::default_target; @@ -191,7 +191,7 @@ impl TryFrom for ToolchainContext { } #[derive(Debug)] -pub struct CargoCheckContext { +pub struct CheckCommandContext { pub cargo_features: Option>, pub cargo_all_features: bool, @@ -202,8 +202,8 @@ pub struct CargoCheckContext { pub rustup_command: Option>, } -impl From for CargoCheckContext { - fn from(opts: CargoCheckOpts) -> Self { +impl From for CheckCommandContext { + fn from(opts: CheckCommandOpts) -> Self { Self { cargo_features: opts.features, cargo_all_features: opts.all_features, diff --git a/src/context/find.rs b/src/context/find.rs index 2eab4b0a..095dcca3 100644 --- a/src/context/find.rs +++ b/src/context/find.rs @@ -1,7 +1,8 @@ use crate::check::RunCommand; use crate::cli::CargoMsrvOpts; +use crate::command::cargo_command::CargoCommand; use crate::context::{ - CargoCheckContext, EnvironmentContext, RustReleasesContext, SearchMethod, ToolchainContext, + CheckCommandContext, EnvironmentContext, RustReleasesContext, SearchMethod, ToolchainContext, UserOutputContext, }; use crate::error::CargoMSRVError; @@ -31,7 +32,7 @@ pub struct FindContext { pub toolchain: ToolchainContext, /// The context for checks to be used with rustup - pub check_cmd: CargoCheckContext, + pub check_cmd: CheckCommandContext, /// Resolved environment options pub environment: EnvironmentContext, @@ -77,7 +78,13 @@ impl FindContext { if let Some(custom) = &self.check_cmd.rustup_command { RunCommand::custom(custom.clone()) } else { - RunCommand::default(self.toolchain.target.clone()) + let cargo_command = CargoCommand::default() + .target(Some(self.toolchain.target.clone())) + .features(self.check_cmd.cargo_features.clone()) + .all_features(self.check_cmd.cargo_all_features) + .no_default_features(self.check_cmd.cargo_no_default_features); + + RunCommand::default(cargo_command) } } } diff --git a/src/context/verify.rs b/src/context/verify.rs index e9973a9d..41f88d65 100644 --- a/src/context/verify.rs +++ b/src/context/verify.rs @@ -1,9 +1,11 @@ use crate::cli::{CargoMsrvOpts, SubCommand}; use crate::context::{ - CargoCheckContext, EnvironmentContext, RustReleasesContext, ToolchainContext, UserOutputContext, + CheckCommandContext, EnvironmentContext, RustReleasesContext, ToolchainContext, + UserOutputContext, }; use crate::check::RunCommand; +use crate::command::cargo_command::CargoCommand; use crate::error::CargoMSRVError; use crate::sub_command::verify::RustVersion; use std::convert::{TryFrom, TryInto}; @@ -26,7 +28,7 @@ pub struct VerifyContext { pub toolchain: ToolchainContext, /// The context for custom checks to be used with rustup - pub check_cmd: CargoCheckContext, + pub check_cmd: CheckCommandContext, /// Resolved environment options pub environment: EnvironmentContext, @@ -76,7 +78,13 @@ impl VerifyContext { if let Some(custom) = &self.check_cmd.rustup_command { RunCommand::custom(custom.clone()) } else { - RunCommand::default(self.toolchain.target.clone()) + let cargo_command = CargoCommand::default() + .target(Some(self.toolchain.target.clone())) + .features(self.check_cmd.cargo_features.clone()) + .all_features(self.check_cmd.cargo_all_features) + .no_default_features(self.check_cmd.cargo_no_default_features); + + RunCommand::default(cargo_command) } } } diff --git a/src/default_target.rs b/src/default_target.rs index b12e5565..51675adb 100644 --- a/src/default_target.rs +++ b/src/default_target.rs @@ -1,5 +1,5 @@ +use crate::command::rustup_command::RustupCommand; use crate::error::{CargoMSRVError, TResult}; -use crate::rustup_command::RustupCommand; /// Uses the `.rustup/settings.toml` file to determine the default target (aka the /// `default_host_triple`) if not set by a user. diff --git a/src/download.rs b/src/download.rs index 1b58b981..f8761886 100644 --- a/src/download.rs +++ b/src/download.rs @@ -1,6 +1,6 @@ +use crate::command::rustup_command::RustupCommand; use crate::error::RustupInstallFailed; use crate::reporter::event::SetupToolchain; -use crate::rustup_command::RustupCommand; use crate::toolchain::ToolchainSpec; use crate::{CargoMSRVError, Reporter, TResult}; diff --git a/src/lib.rs b/src/lib.rs index d2412254..f5dddff4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -32,6 +32,7 @@ use rust_releases::semver; pub mod check; pub mod cli; + pub mod error; pub mod exit_code; pub mod io; @@ -39,6 +40,8 @@ pub mod reporter; pub mod toolchain; pub(crate) mod combinators; + +mod command; mod context; pub(crate) mod default_target; pub(crate) mod dependency_graph; @@ -52,7 +55,6 @@ pub(crate) mod outcome; mod release_index; pub(crate) mod releases_filter; mod rust_release; -pub(crate) mod rustup_command; pub(crate) mod search_method; pub(crate) mod sub_command; pub(crate) mod typed_bool; diff --git a/src/sub_command/find/tests.rs b/src/sub_command/find/tests.rs index d13c6ec0..3d1b0d7e 100644 --- a/src/sub_command/find/tests.rs +++ b/src/sub_command/find/tests.rs @@ -1,7 +1,7 @@ use super::*; use crate::check::TestRunner; use crate::context::{ - CargoCheckContext, EnvironmentContext, ReleaseSource, RustReleasesContext, ToolchainContext, + CheckCommandContext, EnvironmentContext, ReleaseSource, RustReleasesContext, ToolchainContext, UserOutputContext, }; use crate::manifest::bare_version::BareVersion; @@ -247,7 +247,7 @@ fn create_test_context() -> FindContext { toolchain: ToolchainContext { target: "x".to_string(), }, - check_cmd: CargoCheckContext { + check_cmd: CheckCommandContext { cargo_features: None, cargo_all_features: false, cargo_no_default_features: false, diff --git a/tests/find_msrv.rs b/tests/find_msrv.rs index 44690302..19053ae7 100644 --- a/tests/find_msrv.rs +++ b/tests/find_msrv.rs @@ -284,3 +284,100 @@ fn msrv_in_a_virtual_workspace(command: &str, package: &str, expected_version: s assert_eq!(actual_version, &expected_version); } + +#[test] +fn cargo_features_option() { + let folder = fixtures_path().join("cargo-feature-required"); + + let with_args = vec![ + "cargo", + "msrv", + "--features", + "required_feature", + "--path", + folder.to_str().unwrap(), + ]; + + let versions = vec![ + Release::new_stable(semver::Version::new(1, 58, 1)), + Release::new_stable(semver::Version::new(1, 56, 1)), + ]; + + let test_result = find_msrv_with_releases(with_args, versions).unwrap(); + + let version = test_result.msrv().unwrap(); + + assert_eq!(version.major, 1); + assert_eq!(version.minor, 56); + assert_eq!( + test_result.successful_checks(), + &[ + semver::Version::new(1, 58, 1), + semver::Version::new(1, 56, 1) + ] + ); +} + +#[test] +fn cargo_all_features_flag() { + let folder = fixtures_path().join("cargo-feature-required"); + + let with_args = vec![ + "cargo", + "msrv", + "--all-features", + "--path", + folder.to_str().unwrap(), + ]; + + let versions = vec![ + Release::new_stable(semver::Version::new(1, 58, 1)), + Release::new_stable(semver::Version::new(1, 56, 1)), + ]; + + let test_result = find_msrv_with_releases(with_args, versions).unwrap(); + + let version = test_result.msrv().unwrap(); + + assert_eq!(version.major, 1); + assert_eq!(version.minor, 56); + assert_eq!( + test_result.successful_checks(), + &[ + semver::Version::new(1, 58, 1), + semver::Version::new(1, 56, 1) + ] + ); +} + +#[test] +fn cargo_no_default_features_flag() { + let folder = fixtures_path().join("cargo-feature-requires-none"); + + let with_args = vec![ + "cargo", + "msrv", + "--no-default-features", + "--path", + folder.to_str().unwrap(), + ]; + + let versions = vec![ + Release::new_stable(semver::Version::new(1, 58, 1)), + Release::new_stable(semver::Version::new(1, 56, 1)), + ]; + + let test_result = find_msrv_with_releases(with_args, versions).unwrap(); + + let version = test_result.msrv().unwrap(); + + assert_eq!(version.major, 1); + assert_eq!(version.minor, 56); + assert_eq!( + test_result.successful_checks(), + &[ + semver::Version::new(1, 58, 1), + semver::Version::new(1, 56, 1) + ] + ); +} diff --git a/tests/fixtures/cargo-feature-required/.gitignore b/tests/fixtures/cargo-feature-required/.gitignore new file mode 100644 index 00000000..2f88dbac --- /dev/null +++ b/tests/fixtures/cargo-feature-required/.gitignore @@ -0,0 +1,3 @@ +/target +**/*.rs.bk +Cargo.lock \ No newline at end of file diff --git a/tests/fixtures/cargo-feature-required/Cargo.toml b/tests/fixtures/cargo-feature-required/Cargo.toml new file mode 100644 index 00000000..c1af9b94 --- /dev/null +++ b/tests/fixtures/cargo-feature-required/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "requires-cargo-feature" +version = "0.1.0" +edition = "2021" + +[features] +required_feature = [] diff --git a/tests/fixtures/cargo-feature-required/src/lib.rs b/tests/fixtures/cargo-feature-required/src/lib.rs new file mode 100644 index 00000000..63e5872e --- /dev/null +++ b/tests/fixtures/cargo-feature-required/src/lib.rs @@ -0,0 +1,10 @@ +#[cfg(feature = "required_feature")] +fn compile() { + // Rust >= 1.56 + let _: u8 = 1u32.try_into().unwrap(); +} + +#[cfg(not(feature = "required_feature"))] +fn compile() { + compile_error!("Requires 'required_feature' to compile!"); +} diff --git a/tests/fixtures/cargo-feature-requires-none/.gitignore b/tests/fixtures/cargo-feature-requires-none/.gitignore new file mode 100644 index 00000000..2f88dbac --- /dev/null +++ b/tests/fixtures/cargo-feature-requires-none/.gitignore @@ -0,0 +1,3 @@ +/target +**/*.rs.bk +Cargo.lock \ No newline at end of file diff --git a/tests/fixtures/cargo-feature-requires-none/Cargo.toml b/tests/fixtures/cargo-feature-requires-none/Cargo.toml new file mode 100644 index 00000000..1a07bfc9 --- /dev/null +++ b/tests/fixtures/cargo-feature-requires-none/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "requires-cargo-feature" +version = "0.1.0" +edition = "2021" + +[features] +default = ["unrequired_feature"] +unrequired_feature = [] diff --git a/tests/fixtures/cargo-feature-requires-none/src/lib.rs b/tests/fixtures/cargo-feature-requires-none/src/lib.rs new file mode 100644 index 00000000..6164f5dd --- /dev/null +++ b/tests/fixtures/cargo-feature-requires-none/src/lib.rs @@ -0,0 +1,11 @@ +use std::convert::TryInto; + +fn some() { + // Rust >= 1.56 + let _: u8 = 1u32.try_into().unwrap(); +} + +#[cfg(feature = "unrequired_feature")] +fn compile() { + compile_error!("If the 'unrequired_feature' is set, compiling will fail!"); +} From f7b23c1d71a569b17c4255f36f337eff78a410b6 Mon Sep 17 00:00:00 2001 From: Martijn Gribnau Date: Thu, 16 Nov 2023 23:04:33 +0100 Subject: [PATCH 6/6] chore: Update MSRV pre-release check to use version 0.16.0-beta.17 --- .github/workflows/msrv.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/msrv.yml b/.github/workflows/msrv.yml index a0ababfc..49d98570 100644 --- a/.github/workflows/msrv.yml +++ b/.github/workflows/msrv.yml @@ -45,7 +45,7 @@ jobs: with: tool: cargo-binstall - name: install_cargo_msrv_bin - run: cargo binstall --version 0.16.0-beta.15 --no-confirm cargo-msrv + run: cargo binstall --version 0.16.0-beta.17 --no-confirm cargo-msrv - name: version_of_cargo_msrv run: cargo msrv --version - name: run_cargo_msrv