Pass Clippy args also trough RUSTFLAGS
This commit is contained in:
parent
b7db5bfc50
commit
cc9695543e
@ -208,7 +208,6 @@ the lint(s) you are interested in:
|
|||||||
```terminal
|
```terminal
|
||||||
cargo clippy -- -A clippy::all -W clippy::useless_format -W clippy::...
|
cargo clippy -- -A clippy::all -W clippy::useless_format -W clippy::...
|
||||||
```
|
```
|
||||||
Note that if you've run clippy before, this may only take effect after you've modified a file or ran `cargo clean`.
|
|
||||||
|
|
||||||
### Specifying the minimum supported Rust version
|
### Specifying the minimum supported Rust version
|
||||||
|
|
||||||
|
116
src/driver.rs
116
src/driver.rs
@ -1,5 +1,6 @@
|
|||||||
#![feature(rustc_private)]
|
#![feature(rustc_private)]
|
||||||
#![feature(once_cell)]
|
#![feature(once_cell)]
|
||||||
|
#![feature(bool_to_option)]
|
||||||
#![cfg_attr(feature = "deny-warnings", deny(warnings))]
|
#![cfg_attr(feature = "deny-warnings", deny(warnings))]
|
||||||
// warn on lints, that are included in `rust-lang/rust`s bootstrap
|
// warn on lints, that are included in `rust-lang/rust`s bootstrap
|
||||||
#![warn(rust_2018_idioms, unused_lifetimes)]
|
#![warn(rust_2018_idioms, unused_lifetimes)]
|
||||||
@ -19,6 +20,7 @@ use rustc_tools_util::VersionInfo;
|
|||||||
|
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::env;
|
use std::env;
|
||||||
|
use std::iter;
|
||||||
use std::lazy::SyncLazy;
|
use std::lazy::SyncLazy;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::panic;
|
use std::panic;
|
||||||
@ -47,20 +49,6 @@ fn arg_value<'a, T: Deref<Target = str>>(
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_arg_value() {
|
|
||||||
let args = &["--bar=bar", "--foobar", "123", "--foo"];
|
|
||||||
|
|
||||||
assert_eq!(arg_value(&[] as &[&str], "--foobar", |_| true), None);
|
|
||||||
assert_eq!(arg_value(args, "--bar", |_| false), None);
|
|
||||||
assert_eq!(arg_value(args, "--bar", |_| true), Some("bar"));
|
|
||||||
assert_eq!(arg_value(args, "--bar", |p| p == "bar"), Some("bar"));
|
|
||||||
assert_eq!(arg_value(args, "--bar", |p| p == "foo"), None);
|
|
||||||
assert_eq!(arg_value(args, "--foobar", |p| p == "foo"), None);
|
|
||||||
assert_eq!(arg_value(args, "--foobar", |p| p == "123"), Some("123"));
|
|
||||||
assert_eq!(arg_value(args, "--foo", |_| true), None);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct DefaultCallbacks;
|
struct DefaultCallbacks;
|
||||||
impl rustc_driver::Callbacks for DefaultCallbacks {}
|
impl rustc_driver::Callbacks for DefaultCallbacks {}
|
||||||
|
|
||||||
@ -182,6 +170,28 @@ fn toolchain_path(home: Option<String>, toolchain: Option<String>) -> Option<Pat
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn remove_clippy_args<'a, T, U, I>(args: &mut Vec<T>, clippy_args: I)
|
||||||
|
where
|
||||||
|
T: AsRef<str>,
|
||||||
|
U: AsRef<str> + ?Sized + 'a,
|
||||||
|
I: Iterator<Item = &'a U> + Clone,
|
||||||
|
{
|
||||||
|
let args_iter = clippy_args.map(AsRef::as_ref);
|
||||||
|
let args_count = args_iter.clone().count();
|
||||||
|
|
||||||
|
if args_count > 0 {
|
||||||
|
if let Some(start) = args.windows(args_count).enumerate().find_map(|(current, window)| {
|
||||||
|
window
|
||||||
|
.iter()
|
||||||
|
.map(AsRef::as_ref)
|
||||||
|
.eq(args_iter.clone())
|
||||||
|
.then_some(current)
|
||||||
|
}) {
|
||||||
|
args.drain(start..start + args_count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(clippy::too_many_lines)]
|
#[allow(clippy::too_many_lines)]
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
rustc_driver::init_rustc_env_logger();
|
rustc_driver::init_rustc_env_logger();
|
||||||
@ -278,20 +288,9 @@ pub fn main() {
|
|||||||
args.extend(vec!["--sysroot".into(), sys_root]);
|
args.extend(vec!["--sysroot".into(), sys_root]);
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut no_deps = false;
|
let clippy_args = env::var("CLIPPY_ARGS").unwrap_or_default();
|
||||||
let clippy_args = env::var("CLIPPY_ARGS")
|
let clippy_args = clippy_args.split_whitespace();
|
||||||
.unwrap_or_default()
|
let no_deps = clippy_args.clone().any(|flag| flag == "--no-deps");
|
||||||
.split("__CLIPPY_HACKERY__")
|
|
||||||
.filter_map(|s| match s {
|
|
||||||
"" => None,
|
|
||||||
"--no-deps" => {
|
|
||||||
no_deps = true;
|
|
||||||
None
|
|
||||||
},
|
|
||||||
_ => Some(s.to_string()),
|
|
||||||
})
|
|
||||||
.chain(vec!["--cfg".into(), r#"feature="cargo-clippy""#.into()])
|
|
||||||
.collect::<Vec<String>>();
|
|
||||||
|
|
||||||
// We enable Clippy if one of the following conditions is met
|
// We enable Clippy if one of the following conditions is met
|
||||||
// - IF Clippy is run on its test suite OR
|
// - IF Clippy is run on its test suite OR
|
||||||
@ -304,7 +303,11 @@ pub fn main() {
|
|||||||
|
|
||||||
let clippy_enabled = clippy_tests_set || (!cap_lints_allow && (!no_deps || in_primary_package));
|
let clippy_enabled = clippy_tests_set || (!cap_lints_allow && (!no_deps || in_primary_package));
|
||||||
if clippy_enabled {
|
if clippy_enabled {
|
||||||
args.extend(clippy_args);
|
remove_clippy_args(&mut args, iter::once("--no-deps"));
|
||||||
|
args.extend(vec!["--cfg".into(), r#"feature="cargo-clippy""#.into()]);
|
||||||
|
} else {
|
||||||
|
// Remove all flags passed through RUSTFLAGS if Clippy is not enabled.
|
||||||
|
remove_clippy_args(&mut args, clippy_args);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut clippy = ClippyCallbacks;
|
let mut clippy = ClippyCallbacks;
|
||||||
@ -315,3 +318,58 @@ pub fn main() {
|
|||||||
rustc_driver::RunCompiler::new(&args, callbacks).run()
|
rustc_driver::RunCompiler::new(&args, callbacks).run()
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_arg_value() {
|
||||||
|
let args = &["--bar=bar", "--foobar", "123", "--foo"];
|
||||||
|
|
||||||
|
assert_eq!(arg_value(&[] as &[&str], "--foobar", |_| true), None);
|
||||||
|
assert_eq!(arg_value(args, "--bar", |_| false), None);
|
||||||
|
assert_eq!(arg_value(args, "--bar", |_| true), Some("bar"));
|
||||||
|
assert_eq!(arg_value(args, "--bar", |p| p == "bar"), Some("bar"));
|
||||||
|
assert_eq!(arg_value(args, "--bar", |p| p == "foo"), None);
|
||||||
|
assert_eq!(arg_value(args, "--foobar", |p| p == "foo"), None);
|
||||||
|
assert_eq!(arg_value(args, "--foobar", |p| p == "123"), Some("123"));
|
||||||
|
assert_eq!(arg_value(args, "--foo", |_| true), None);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn removes_clippy_args_from_start() {
|
||||||
|
let mut args = vec!["-D", "clippy::await_holding_lock", "--cfg", r#"feature="some_feat""#];
|
||||||
|
let clippy_args = ["-D", "clippy::await_holding_lock"].iter();
|
||||||
|
|
||||||
|
remove_clippy_args(&mut args, clippy_args);
|
||||||
|
assert_eq!(args, &["--cfg", r#"feature="some_feat""#]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn removes_clippy_args_from_end() {
|
||||||
|
let mut args = vec!["-Zui-testing", "-A", "clippy::empty_loop", "--no-deps"];
|
||||||
|
let clippy_args = ["-A", "clippy::empty_loop", "--no-deps"].iter();
|
||||||
|
|
||||||
|
remove_clippy_args(&mut args, clippy_args);
|
||||||
|
assert_eq!(args, &["-Zui-testing"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn removes_clippy_args_from_middle() {
|
||||||
|
let mut args = vec!["-Zui-testing", "-W", "clippy::filter_map", "-L", "serde"];
|
||||||
|
let clippy_args = ["-W", "clippy::filter_map"].iter();
|
||||||
|
|
||||||
|
remove_clippy_args(&mut args, clippy_args);
|
||||||
|
assert_eq!(args, &["-Zui-testing", "-L", "serde"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn no_clippy_args_to_remove() {
|
||||||
|
let mut args = vec!["-Zui-testing", "-L", "serde"];
|
||||||
|
let clippy_args: [&str; 0] = [];
|
||||||
|
|
||||||
|
remove_clippy_args(&mut args, clippy_args.iter());
|
||||||
|
assert_eq!(args, &["-Zui-testing", "-L", "serde"]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
98
src/main.rs
98
src/main.rs
@ -1,3 +1,4 @@
|
|||||||
|
#![feature(bool_to_option)]
|
||||||
#![cfg_attr(feature = "deny-warnings", deny(warnings))]
|
#![cfg_attr(feature = "deny-warnings", deny(warnings))]
|
||||||
// warn on lints, that are included in `rust-lang/rust`s bootstrap
|
// warn on lints, that are included in `rust-lang/rust`s bootstrap
|
||||||
#![warn(rust_2018_idioms, unused_lifetimes)]
|
#![warn(rust_2018_idioms, unused_lifetimes)]
|
||||||
@ -62,11 +63,12 @@ struct ClippyCmd {
|
|||||||
unstable_options: bool,
|
unstable_options: bool,
|
||||||
cargo_subcommand: &'static str,
|
cargo_subcommand: &'static str,
|
||||||
args: Vec<String>,
|
args: Vec<String>,
|
||||||
clippy_args: Vec<String>,
|
rustflags: Option<String>,
|
||||||
|
clippy_args: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ClippyCmd {
|
impl ClippyCmd {
|
||||||
fn new<I>(mut old_args: I) -> Self
|
fn new<I>(mut old_args: I, rustflags: Option<String>) -> Self
|
||||||
where
|
where
|
||||||
I: Iterator<Item = String>,
|
I: Iterator<Item = String>,
|
||||||
{
|
{
|
||||||
@ -99,16 +101,19 @@ impl ClippyCmd {
|
|||||||
args.insert(0, "+nightly".to_string());
|
args.insert(0, "+nightly".to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut clippy_args: Vec<String> = old_args.collect();
|
let mut clippy_args = old_args.collect::<Vec<String>>().join(" ");
|
||||||
if cargo_subcommand == "fix" && !clippy_args.iter().any(|arg| arg == "--no-deps") {
|
if cargo_subcommand == "fix" && !clippy_args.contains("--no-deps") {
|
||||||
clippy_args.push("--no-deps".into());
|
clippy_args = format!("{} --no-deps", clippy_args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let has_args = !clippy_args.is_empty();
|
||||||
ClippyCmd {
|
ClippyCmd {
|
||||||
unstable_options,
|
unstable_options,
|
||||||
cargo_subcommand,
|
cargo_subcommand,
|
||||||
args,
|
args,
|
||||||
clippy_args,
|
rustflags: has_args
|
||||||
|
.then(|| rustflags.map_or_else(|| clippy_args.clone(), |flags| format!("{} {}", clippy_args, flags))),
|
||||||
|
clippy_args: has_args.then_some(clippy_args),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,18 +155,19 @@ impl ClippyCmd {
|
|||||||
|
|
||||||
fn into_std_cmd(self) -> Command {
|
fn into_std_cmd(self) -> Command {
|
||||||
let mut cmd = Command::new("cargo");
|
let mut cmd = Command::new("cargo");
|
||||||
let clippy_args: String = self
|
|
||||||
.clippy_args
|
|
||||||
.iter()
|
|
||||||
.map(|arg| format!("{}__CLIPPY_HACKERY__", arg))
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
cmd.env(self.path_env(), Self::path())
|
cmd.env(self.path_env(), Self::path())
|
||||||
.envs(ClippyCmd::target_dir())
|
.envs(ClippyCmd::target_dir())
|
||||||
.env("CLIPPY_ARGS", clippy_args)
|
|
||||||
.arg(self.cargo_subcommand)
|
.arg(self.cargo_subcommand)
|
||||||
.args(&self.args);
|
.args(&self.args);
|
||||||
|
|
||||||
|
// HACK: pass Clippy args to the driver *also* through RUSTFLAGS.
|
||||||
|
// This guarantees that new builds will be triggered when Clippy flags change.
|
||||||
|
if let (Some(clippy_args), Some(rustflags)) = (self.clippy_args, self.rustflags) {
|
||||||
|
cmd.env("CLIPPY_ARGS", clippy_args);
|
||||||
|
cmd.env("RUSTFLAGS", rustflags);
|
||||||
|
}
|
||||||
|
|
||||||
cmd
|
cmd
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -170,7 +176,7 @@ fn process<I>(old_args: I) -> Result<(), i32>
|
|||||||
where
|
where
|
||||||
I: Iterator<Item = String>,
|
I: Iterator<Item = String>,
|
||||||
{
|
{
|
||||||
let cmd = ClippyCmd::new(old_args);
|
let cmd = ClippyCmd::new(old_args, env::var("RUSTFLAGS").ok());
|
||||||
|
|
||||||
let mut cmd = cmd.into_std_cmd();
|
let mut cmd = cmd.into_std_cmd();
|
||||||
|
|
||||||
@ -195,7 +201,7 @@ mod tests {
|
|||||||
#[should_panic]
|
#[should_panic]
|
||||||
fn fix_without_unstable() {
|
fn fix_without_unstable() {
|
||||||
let args = "cargo clippy --fix".split_whitespace().map(ToString::to_string);
|
let args = "cargo clippy --fix".split_whitespace().map(ToString::to_string);
|
||||||
let _ = ClippyCmd::new(args);
|
let _ = ClippyCmd::new(args, None);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -203,7 +209,8 @@ mod tests {
|
|||||||
let args = "cargo clippy --fix -Zunstable-options"
|
let args = "cargo clippy --fix -Zunstable-options"
|
||||||
.split_whitespace()
|
.split_whitespace()
|
||||||
.map(ToString::to_string);
|
.map(ToString::to_string);
|
||||||
let cmd = ClippyCmd::new(args);
|
let cmd = ClippyCmd::new(args, None);
|
||||||
|
|
||||||
assert_eq!("fix", cmd.cargo_subcommand);
|
assert_eq!("fix", cmd.cargo_subcommand);
|
||||||
assert_eq!("RUSTC_WORKSPACE_WRAPPER", cmd.path_env());
|
assert_eq!("RUSTC_WORKSPACE_WRAPPER", cmd.path_env());
|
||||||
assert!(cmd.args.iter().any(|arg| arg.ends_with("unstable-options")));
|
assert!(cmd.args.iter().any(|arg| arg.ends_with("unstable-options")));
|
||||||
@ -214,8 +221,9 @@ mod tests {
|
|||||||
let args = "cargo clippy --fix -Zunstable-options"
|
let args = "cargo clippy --fix -Zunstable-options"
|
||||||
.split_whitespace()
|
.split_whitespace()
|
||||||
.map(ToString::to_string);
|
.map(ToString::to_string);
|
||||||
let cmd = ClippyCmd::new(args);
|
let cmd = ClippyCmd::new(args, None);
|
||||||
assert!(cmd.clippy_args.iter().any(|arg| arg == "--no-deps"));
|
|
||||||
|
assert!(cmd.clippy_args.unwrap().contains("--no-deps"));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -223,14 +231,16 @@ mod tests {
|
|||||||
let args = "cargo clippy --fix -Zunstable-options -- --no-deps"
|
let args = "cargo clippy --fix -Zunstable-options -- --no-deps"
|
||||||
.split_whitespace()
|
.split_whitespace()
|
||||||
.map(ToString::to_string);
|
.map(ToString::to_string);
|
||||||
let cmd = ClippyCmd::new(args);
|
let cmd = ClippyCmd::new(args, None);
|
||||||
assert_eq!(cmd.clippy_args.iter().filter(|arg| *arg == "--no-deps").count(), 1);
|
|
||||||
|
assert_eq!(1, cmd.clippy_args.unwrap().matches("--no-deps").count());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn check() {
|
fn check() {
|
||||||
let args = "cargo clippy".split_whitespace().map(ToString::to_string);
|
let args = "cargo clippy".split_whitespace().map(ToString::to_string);
|
||||||
let cmd = ClippyCmd::new(args);
|
let cmd = ClippyCmd::new(args, None);
|
||||||
|
|
||||||
assert_eq!("check", cmd.cargo_subcommand);
|
assert_eq!("check", cmd.cargo_subcommand);
|
||||||
assert_eq!("RUSTC_WRAPPER", cmd.path_env());
|
assert_eq!("RUSTC_WRAPPER", cmd.path_env());
|
||||||
}
|
}
|
||||||
@ -240,8 +250,54 @@ mod tests {
|
|||||||
let args = "cargo clippy -Zunstable-options"
|
let args = "cargo clippy -Zunstable-options"
|
||||||
.split_whitespace()
|
.split_whitespace()
|
||||||
.map(ToString::to_string);
|
.map(ToString::to_string);
|
||||||
let cmd = ClippyCmd::new(args);
|
let cmd = ClippyCmd::new(args, None);
|
||||||
|
|
||||||
assert_eq!("check", cmd.cargo_subcommand);
|
assert_eq!("check", cmd.cargo_subcommand);
|
||||||
assert_eq!("RUSTC_WORKSPACE_WRAPPER", cmd.path_env());
|
assert_eq!("RUSTC_WORKSPACE_WRAPPER", cmd.path_env());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn clippy_args_into_rustflags() {
|
||||||
|
let args = "cargo clippy -- -W clippy::as_conversions"
|
||||||
|
.split_whitespace()
|
||||||
|
.map(ToString::to_string);
|
||||||
|
let rustflags = None;
|
||||||
|
let cmd = ClippyCmd::new(args, rustflags);
|
||||||
|
|
||||||
|
assert_eq!("-W clippy::as_conversions", cmd.rustflags.unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn clippy_args_respect_existing_rustflags() {
|
||||||
|
let args = "cargo clippy -- -D clippy::await_holding_lock"
|
||||||
|
.split_whitespace()
|
||||||
|
.map(ToString::to_string);
|
||||||
|
let rustflags = Some(r#"--cfg feature="some_feat""#.into());
|
||||||
|
let cmd = ClippyCmd::new(args, rustflags);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
r#"-D clippy::await_holding_lock --cfg feature="some_feat""#,
|
||||||
|
cmd.rustflags.unwrap()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn no_env_change_if_no_clippy_args() {
|
||||||
|
let args = "cargo clippy".split_whitespace().map(ToString::to_string);
|
||||||
|
let rustflags = Some(r#"--cfg feature="some_feat""#.into());
|
||||||
|
let cmd = ClippyCmd::new(args, rustflags);
|
||||||
|
|
||||||
|
assert!(cmd.clippy_args.is_none());
|
||||||
|
assert!(cmd.rustflags.is_none());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn no_env_change_if_no_clippy_args_nor_rustflags() {
|
||||||
|
let args = "cargo clippy".split_whitespace().map(ToString::to_string);
|
||||||
|
let rustflags = None;
|
||||||
|
let cmd = ClippyCmd::new(args, rustflags);
|
||||||
|
|
||||||
|
assert!(cmd.clippy_args.is_none());
|
||||||
|
assert!(cmd.rustflags.is_none());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ fn dogfood_clippy() {
|
|||||||
.current_dir(root_dir)
|
.current_dir(root_dir)
|
||||||
.env("CLIPPY_DOGFOOD", "1")
|
.env("CLIPPY_DOGFOOD", "1")
|
||||||
.env("CARGO_INCREMENTAL", "0")
|
.env("CARGO_INCREMENTAL", "0")
|
||||||
.arg("clippy-preview")
|
.arg("clippy")
|
||||||
.arg("--all-targets")
|
.arg("--all-targets")
|
||||||
.arg("--all-features")
|
.arg("--all-features")
|
||||||
.arg("--")
|
.arg("--")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user