From 729809645730e89847ade17631ead30cf05c3d77 Mon Sep 17 00:00:00 2001 From: Martijn Gribnau Date: Mon, 11 Nov 2024 02:27:51 +0100 Subject: [PATCH 1/5] Refactor to_{find,verify}_context to return the context immediately --- src/context/mod.rs | 32 ++++++++++++++++++-------------- tests/common/sub_cmd_find.rs | 2 +- tests/common/sub_cmd_verify.rs | 2 +- 3 files changed, 20 insertions(+), 16 deletions(-) diff --git a/src/context/mod.rs b/src/context/mod.rs index a3c81fb3..5f335236 100644 --- a/src/context/mod.rs +++ b/src/context/mod.rs @@ -85,22 +85,26 @@ impl Context { } } - /// Returns the inner find context, if it was present. - pub fn to_find_context(self) -> Option { - if let Self::Find(ctx) = self { - Some(ctx) - } else { - None - } + /// Returns the inner find context + /// + /// **Panics** + /// + /// Panics if the context does not match with `Find` + pub fn to_find_context(self) -> FindContext { + let Self::Find(ctx) = self else { + unreachable!("Find Context does not exist") + }; + + ctx } - /// Returns the inner find context, if it was present. - pub fn to_verify_context(self) -> Option { - if let Self::Verify(ctx) = self { - Some(ctx) - } else { - None - } + /// Returns the inner verify context + pub fn to_verify_context(self) -> VerifyContext { + let Self::Verify(ctx) = self else { + unreachable!("Find Context does not exist") + }; + + ctx } } diff --git a/tests/common/sub_cmd_find.rs b/tests/common/sub_cmd_find.rs index 500fd3a8..3c72e395 100644 --- a/tests/common/sub_cmd_find.rs +++ b/tests/common/sub_cmd_find.rs @@ -58,7 +58,7 @@ pub fn find_msrv_with_releases< let matches = CargoCli::parse_args(with_args); let opts = matches.to_cargo_msrv_cli().to_opts(); let ctx = Context::try_from(opts)?; - let find_ctx = ctx.to_find_context().unwrap(); + let find_ctx = ctx.to_find_context(); // Limit the available versions: this ensures we don't need to incrementally install more toolchains // as more Rust toolchains become available. diff --git a/tests/common/sub_cmd_verify.rs b/tests/common/sub_cmd_verify.rs index 5b6ae3cf..803b626a 100644 --- a/tests/common/sub_cmd_verify.rs +++ b/tests/common/sub_cmd_verify.rs @@ -17,7 +17,7 @@ where let matches = CargoCli::parse_args(with_args); let opts = matches.to_cargo_msrv_cli().to_opts(); let ctx = Context::try_from(opts)?; - let verify_ctx = ctx.to_verify_context().unwrap(); + let verify_ctx = ctx.to_verify_context(); // Limit the available versions: this ensures we don't need to incrementally install more toolchains // as more Rust toolchains become available. From 85cd17fac106eb24e5280f20b843269913ca5716 Mon Sep 17 00:00:00 2001 From: Martijn Gribnau Date: Mon, 11 Nov 2024 02:40:02 +0100 Subject: [PATCH 2/5] Scaffold cargo msrv doctor contexts and subcommand --- src/context/doctor.rs | 21 +++++++++++++++++++++ src/context/mod.rs | 18 ++++++++++++------ src/lib.rs | 5 ++++- src/sub_command/doctor.rs | 16 ++++++++++++++++ src/sub_command/mod.rs | 16 ++++++++++++---- 5 files changed, 65 insertions(+), 11 deletions(-) create mode 100644 src/context/doctor.rs create mode 100644 src/sub_command/doctor.rs diff --git a/src/context/doctor.rs b/src/context/doctor.rs new file mode 100644 index 00000000..9a76093e --- /dev/null +++ b/src/context/doctor.rs @@ -0,0 +1,21 @@ +use crate::cli::CargoMsrvOpts; +use crate::context::EnvironmentContext; +use crate::error::CargoMSRVError; + +#[derive(Debug)] +pub struct DoctorContext { + /// Resolved environment options + pub environment: EnvironmentContext, +} + +impl TryFrom for DoctorContext { + type Error = CargoMSRVError; + + fn try_from(opts: CargoMsrvOpts) -> Result { + let CargoMsrvOpts { shared_opts, .. } = opts; + + Ok(Self { + environment: (&shared_opts).try_into()?, + }) + } +} diff --git a/src/context/mod.rs b/src/context/mod.rs index 5f335236..07c20b66 100644 --- a/src/context/mod.rs +++ b/src/context/mod.rs @@ -19,24 +19,27 @@ use std::path::Path; use std::str::FromStr; use std::{env, fmt}; -pub mod find; -pub mod list; -pub mod set; -pub mod show; -pub mod verify; - use crate::cli::custom_check_opts::CustomCheckOpts; use crate::cli::rust_releases_opts::Edition; use crate::cli::{CargoMsrvOpts, SubCommand}; use crate::log_level::LogLevel; use crate::reporter::event::SelectedPackage; use crate::rust::default_target::default_target; + +pub use doctor::DoctorContext; pub use find::FindContext; pub use list::ListContext; pub use set::SetContext; pub use show::ShowContext; pub use verify::VerifyContext; +pub mod doctor; +pub mod find; +pub mod list; +pub mod set; +pub mod show; +pub mod verify; + /// A `context` in `cargo-msrv`, is a definitive and flattened set of options, /// required for the program (and its selected sub-command) to function. /// @@ -57,6 +60,7 @@ pub use verify::VerifyContext; /// data. #[derive(Debug)] pub enum Context { + Doctor(DoctorContext), Find(FindContext), List(ListContext), Set(SetContext), @@ -67,6 +71,7 @@ pub enum Context { impl Context { pub fn reporting_name(&self) -> &'static str { match self { + Context::Doctor(_) => "Doctor", Context::Find(_) => "find", Context::List(_) => "list", Context::Set(_) => "set", @@ -77,6 +82,7 @@ impl Context { pub fn environment_context(&self) -> &EnvironmentContext { match self { + Context::Doctor(ctx) => &ctx.environment, Context::Find(ctx) => &ctx.environment, Context::List(ctx) => &ctx.environment, Context::Set(ctx) => &ctx.environment, diff --git a/src/lib.rs b/src/lib.rs index c0d78ba4..4caa3763 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -22,7 +22,7 @@ extern crate tracing; pub use crate::context::{Context, OutputFormat, TracingOptions, TracingTargetOption}; pub use crate::outcome::Compatibility; -pub use crate::sub_command::{Find, List, Set, Show, SubCommand, Verify}; +pub use crate::sub_command::{Doctor, Find, List, Set, Show, SubCommand, Verify}; use crate::compatibility::RustupToolchainCheck; use crate::context::ReleaseSource; @@ -61,6 +61,9 @@ pub fn run_app(ctx: &Context, reporter: &impl Reporter) -> TResult<()> { reporter.report_event(SubcommandInit::new(ctx.reporting_name()))?; match ctx { + Context::Doctor(ctx) => { + Doctor.run(ctx, reporter)?; + } Context::Find(ctx) => { let index = release_index::fetch_index(reporter, ctx.rust_releases.release_source)?; diff --git a/src/sub_command/doctor.rs b/src/sub_command/doctor.rs new file mode 100644 index 00000000..b70090b5 --- /dev/null +++ b/src/sub_command/doctor.rs @@ -0,0 +1,16 @@ +use crate::context::DoctorContext; +use crate::error::TResult; +use crate::reporter::Reporter; +use crate::SubCommand; + +#[derive(Default)] +pub struct Doctor; + +impl SubCommand for Doctor { + type Context = DoctorContext; + type Output = (); + + fn run(&self, _ctx: &Self::Context, _reporter: &impl Reporter) -> TResult { + todo!("Implement cargo msrv doctor!") + } +} diff --git a/src/sub_command/mod.rs b/src/sub_command/mod.rs index 2acf6f16..b1d6cdb2 100644 --- a/src/sub_command/mod.rs +++ b/src/sub_command/mod.rs @@ -1,8 +1,18 @@ +use crate::reporter::Reporter; +use crate::TResult; + +/// Find MSRV related issues +/// +/// # Example (CLI) +/// +/// `cargo msrv doctor` +pub use doctor::Doctor; + /// Find the MSRV of a Rust package. /// /// # Example (CLI) /// -/// `cargo msrv` +/// `cargo msrv find` pub use find::Find; /// List the MSRV's of libraries you depend on. @@ -38,9 +48,7 @@ pub use set::Set; /// `cargo msrv show` pub use show::Show; -use crate::reporter::Reporter; -use crate::TResult; - +pub mod doctor; pub mod find; pub mod list; pub mod set; From 0b5ef8e185c26b5a08b7101f8aa89e03d0be6860 Mon Sep 17 00:00:00 2001 From: Martijn Gribnau Date: Mon, 11 Nov 2024 02:53:49 +0100 Subject: [PATCH 3/5] Add cargo msrv doctor CLI --- src/cli/mod.rs | 2 ++ src/context/mod.rs | 1 + 2 files changed, 3 insertions(+) diff --git a/src/cli/mod.rs b/src/cli/mod.rs index f7bd0f5e..98c8a464 100644 --- a/src/cli/mod.rs +++ b/src/cli/mod.rs @@ -104,6 +104,8 @@ pub struct CargoMsrvOpts { #[derive(Debug, Subcommand)] #[command(propagate_version = true)] pub enum SubCommand { + /// Find & fix MSRV related issues + Doctor, /// Find the MSRV Find(FindOpts), /// Display the MSRV's of dependencies diff --git a/src/context/mod.rs b/src/context/mod.rs index 07c20b66..f19a4b06 100644 --- a/src/context/mod.rs +++ b/src/context/mod.rs @@ -119,6 +119,7 @@ impl TryFrom for Context { fn try_from(opts: CargoMsrvOpts) -> Result { let ctx = match opts.subcommand { + SubCommand::Doctor => Self::Doctor(DoctorContext::try_from(opts)?), SubCommand::Find(_) => Self::Find(FindContext::try_from(opts)?), SubCommand::List(_) => Self::List(ListContext::try_from(opts)?), SubCommand::Set(_) => Self::Set(SetContext::try_from(opts)?), From f6d500f5f07774dca4fe89c548b439f4a0ea5903 Mon Sep 17 00:00:00 2001 From: Martijn Gribnau Date: Mon, 11 Nov 2024 03:00:10 +0100 Subject: [PATCH 4/5] Add fix flag to doctor subcommand --- src/cli/mod.rs | 10 +++++++++- src/context/doctor.rs | 17 +++++++++++++++-- src/context/mod.rs | 2 +- 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/cli/mod.rs b/src/cli/mod.rs index 98c8a464..96534b76 100644 --- a/src/cli/mod.rs +++ b/src/cli/mod.rs @@ -105,7 +105,7 @@ pub struct CargoMsrvOpts { #[command(propagate_version = true)] pub enum SubCommand { /// Find & fix MSRV related issues - Doctor, + Doctor(DoctorOpts), /// Find the MSRV Find(FindOpts), /// Display the MSRV's of dependencies @@ -120,6 +120,14 @@ pub enum SubCommand { Verify(VerifyOpts), } +#[derive(Debug, Args)] +#[command(next_help_heading = "Doctor options")] +pub struct DoctorOpts { + /// Try to fix the reported issues + #[arg(long)] + pub fix: bool, +} + // Cli Options for top-level cargo-msrv (find) command #[derive(Debug, Args)] #[command(next_help_heading = "Find MSRV options")] diff --git a/src/context/doctor.rs b/src/context/doctor.rs index 9a76093e..bd89621b 100644 --- a/src/context/doctor.rs +++ b/src/context/doctor.rs @@ -1,9 +1,12 @@ -use crate::cli::CargoMsrvOpts; +use crate::cli::{CargoMsrvOpts, SubCommand}; use crate::context::EnvironmentContext; use crate::error::CargoMSRVError; #[derive(Debug)] pub struct DoctorContext { + /// Try and fix the issues found! + pub fix: bool, + /// Resolved environment options pub environment: EnvironmentContext, } @@ -12,9 +15,19 @@ impl TryFrom for DoctorContext { type Error = CargoMSRVError; fn try_from(opts: CargoMsrvOpts) -> Result { - let CargoMsrvOpts { shared_opts, .. } = opts; + let CargoMsrvOpts { + shared_opts, + subcommand, + .. + } = opts; + + let doctor_opts = match subcommand { + SubCommand::Doctor(opts) => opts, + _ => unreachable!("This should never happen. The subcommand is not `doctor`!"), + }; Ok(Self { + fix: doctor_opts.fix, environment: (&shared_opts).try_into()?, }) } diff --git a/src/context/mod.rs b/src/context/mod.rs index f19a4b06..7ae273e9 100644 --- a/src/context/mod.rs +++ b/src/context/mod.rs @@ -119,7 +119,7 @@ impl TryFrom for Context { fn try_from(opts: CargoMsrvOpts) -> Result { let ctx = match opts.subcommand { - SubCommand::Doctor => Self::Doctor(DoctorContext::try_from(opts)?), + SubCommand::Doctor(_) => Self::Doctor(DoctorContext::try_from(opts)?), SubCommand::Find(_) => Self::Find(FindContext::try_from(opts)?), SubCommand::List(_) => Self::List(ListContext::try_from(opts)?), SubCommand::Set(_) => Self::Set(SetContext::try_from(opts)?), From e1eaebf23311fc044bbc90e290642c84f7c7f8de Mon Sep 17 00:00:00 2001 From: Martijn Gribnau Date: Thu, 21 Nov 2024 16:23:31 +0100 Subject: [PATCH 5/5] todo! --- src/sub_command/doctor.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/sub_command/doctor.rs b/src/sub_command/doctor.rs index b70090b5..e2cfe2f5 100644 --- a/src/sub_command/doctor.rs +++ b/src/sub_command/doctor.rs @@ -1,6 +1,9 @@ +use crate::cli::rust_releases_opts::Edition; use crate::context::DoctorContext; use crate::error::TResult; +use crate::manifest::bare_version::BareVersion; use crate::reporter::Reporter; +use crate::sub_command::verify::RustVersion; use crate::SubCommand; #[derive(Default)] @@ -14,3 +17,13 @@ impl SubCommand for Doctor { todo!("Implement cargo msrv doctor!") } } + +struct IssueAnalyzer { + msrv_cargo_toml: BareVersion, + edition: Edition, +} + +struct MsrvSource { + cargo_toml: Option, + clippy_toml: Option, +}