X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fmain.rs;h=6bd4123ddeb45d92917f1dd043fa9d09ecf208de;hb=a9e9b7f9b2ad52035fe7b57bb0fc8ba62d649c33;hp=05e0c58f88d41252ef99ed0b2d537147790e59e4;hpb=265318dba93a3363255a4d8eac9aefd53a05673a;p=rust.git diff --git a/src/main.rs b/src/main.rs index 05e0c58f88d..6bd4123ddeb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,12 @@ -use rustc_tools_util::*; +#![cfg_attr(feature = "deny-warnings", deny(warnings))] +// warn on lints, that are included in `rust-lang/rust`s bootstrap +#![warn(rust_2018_idioms, unused_lifetimes)] + +use rustc_tools_util::VersionInfo; +use std::env; +use std::ffi::OsString; +use std::path::PathBuf; +use std::process::{self, Command}; const CARGO_CLIPPY_HELP: &str = r#"Checks a package to catch common mistakes and improve your Rust code. @@ -35,67 +43,115 @@ fn show_version() { pub fn main() { // Check for version and help flags even when invoked as 'cargo-clippy' - if std::env::args().any(|a| a == "--help" || a == "-h") { + if env::args().any(|a| a == "--help" || a == "-h") { show_help(); return; } - if std::env::args().any(|a| a == "--version" || a == "-V") { + if env::args().any(|a| a == "--version" || a == "-V") { show_version(); return; } - if let Err(code) = process(std::env::args().skip(2)) { - std::process::exit(code); + if let Err(code) = process(env::args().skip(2)) { + process::exit(code); } } -fn process(mut old_args: I) -> Result<(), i32> -where - I: Iterator, -{ - let mut args = vec!["check".to_owned()]; +struct ClippyCmd { + cargo_subcommand: &'static str, + args: Vec, + clippy_args: Vec, +} + +impl ClippyCmd { + fn new(mut old_args: I) -> Self + where + I: Iterator, + { + let mut cargo_subcommand = "check"; + let mut args = vec![]; + + for arg in old_args.by_ref() { + match arg.as_str() { + "--fix" => { + cargo_subcommand = "fix"; + continue; + }, + "--" => break, + _ => {}, + } + + args.push(arg); + } + + let mut clippy_args: Vec = old_args.collect(); + if cargo_subcommand == "fix" && !clippy_args.iter().any(|arg| arg == "--no-deps") { + clippy_args.push("--no-deps".into()); + } - for arg in old_args.by_ref() { - if arg == "--" { - break; + ClippyCmd { + cargo_subcommand, + args, + clippy_args, } - args.push(arg); } - let clippy_args: String = old_args.map(|arg| format!("{}__CLIPPY_HACKERY__", arg)).collect(); + fn path() -> PathBuf { + let mut path = env::current_exe() + .expect("current executable path invalid") + .with_file_name("clippy-driver"); + + if cfg!(windows) { + path.set_extension("exe"); + } - let mut path = std::env::current_exe() - .expect("current executable path invalid") - .with_file_name("clippy-driver"); - if cfg!(windows) { - path.set_extension("exe"); + path } - let target_dir = std::env::var_os("CLIPPY_DOGFOOD") - .map(|_| { - std::env::var_os("CARGO_MANIFEST_DIR").map_or_else( - || std::ffi::OsString::from("clippy_dogfood"), - |d| { - std::path::PathBuf::from(d) - .join("target") - .join("dogfood") - .into_os_string() - }, - ) - }) - .map(|p| ("CARGO_TARGET_DIR", p)); + fn target_dir() -> Option<(&'static str, OsString)> { + env::var_os("CLIPPY_DOGFOOD") + .map(|_| { + env::var_os("CARGO_MANIFEST_DIR").map_or_else( + || std::ffi::OsString::from("clippy_dogfood"), + |d| { + std::path::PathBuf::from(d) + .join("target") + .join("dogfood") + .into_os_string() + }, + ) + }) + .map(|p| ("CARGO_TARGET_DIR", p)) + } - // Don't run the dogfood tests on beta - if std::env::var_os("CLIPPY_DOGFOOD").is_some() && cfg!(windows) { - return Ok(()) + fn into_std_cmd(self) -> Command { + let mut cmd = Command::new("cargo"); + let clippy_args: String = self + .clippy_args + .iter() + .map(|arg| format!("{}__CLIPPY_HACKERY__", arg)) + .collect(); + + cmd.env("RUSTC_WORKSPACE_WRAPPER", Self::path()) + .envs(ClippyCmd::target_dir()) + .env("CLIPPY_ARGS", clippy_args) + .arg(self.cargo_subcommand) + .args(&self.args); + + cmd } +} - let exit_status = std::process::Command::new("cargo") - .args(&args) - .env("RUSTC_WRAPPER", path) - .env("CLIPPY_ARGS", clippy_args) - .envs(target_dir) +fn process(old_args: I) -> Result<(), i32> +where + I: Iterator, +{ + let cmd = ClippyCmd::new(old_args); + + let mut cmd = cmd.into_std_cmd(); + + let exit_status = cmd .spawn() .expect("could not run cargo") .wait() @@ -107,3 +163,39 @@ fn process(mut old_args: I) -> Result<(), i32> Err(exit_status.code().unwrap_or(-1)) } } + +#[cfg(test)] +mod tests { + use super::ClippyCmd; + + #[test] + fn fix() { + let args = "cargo clippy --fix".split_whitespace().map(ToString::to_string); + let cmd = ClippyCmd::new(args); + assert_eq!("fix", cmd.cargo_subcommand); + assert!(!cmd.args.iter().any(|arg| arg.ends_with("unstable-options"))); + } + + #[test] + fn fix_implies_no_deps() { + let args = "cargo clippy --fix".split_whitespace().map(ToString::to_string); + let cmd = ClippyCmd::new(args); + assert!(cmd.clippy_args.iter().any(|arg| arg == "--no-deps")); + } + + #[test] + fn no_deps_not_duplicated_with_fix() { + let args = "cargo clippy --fix -- --no-deps" + .split_whitespace() + .map(ToString::to_string); + let cmd = ClippyCmd::new(args); + assert_eq!(cmd.clippy_args.iter().filter(|arg| *arg == "--no-deps").count(), 1); + } + + #[test] + fn check() { + let args = "cargo clippy".split_whitespace().map(ToString::to_string); + let cmd = ClippyCmd::new(args); + assert_eq!("check", cmd.cargo_subcommand); + } +}