about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJeremy Fitzhardinge <jsgf@fb.com>2019-01-15 10:56:09 -0800
committerJeremy Fitzhardinge <jeremy@goop.org>2019-02-02 11:43:20 -0800
commitb5fd0108b3a6b8a9626645ac174cf653de576135 (patch)
treea988f15a03dc859290f9833a4dd5ecca520048b5
parent27b5dd8886ac0423e059c0817b55a4e618b344a0 (diff)
downloadrust-b5fd0108b3a6b8a9626645ac174cf653de576135.tar.gz
rust-b5fd0108b3a6b8a9626645ac174cf653de576135.zip
clippy-driver: more robust test to see if we're clippy-enabled
Rather than looking for a fixed --emit arg set, just check to see
if we're emitting metadata at all. This makes it more robust to
being invoked by tools other than cargo (or if cargo changes its
invocation).

Issue #3663
-rw-r--r--Cargo.toml1
-rw-r--r--src/driver.rs42
2 files changed, 41 insertions, 2 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 868f21c1a49..c3710485027 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -34,7 +34,6 @@ path = "src/main.rs"
 
 [[bin]]
 name = "clippy-driver"
-test = false
 path = "src/driver.rs"
 
 [dependencies]
diff --git a/src/driver.rs b/src/driver.rs
index b41895f3c2b..d290e403a31 100644
--- a/src/driver.rs
+++ b/src/driver.rs
@@ -20,6 +20,46 @@ fn show_version() {
     println!(env!("CARGO_PKG_VERSION"));
 }
 
+/// If a command-line option matches `find_arg`, then apply the predicate `pred` on its value. If
+/// true, then return it. The parameter is assumed to be either `--arg=value` or `--arg value`.
+fn arg_value<'a>(
+    args: impl IntoIterator<Item = &'a String>,
+    find_arg: &str,
+    pred: impl Fn(&str) -> bool,
+) -> Option<&'a str> {
+    let mut args = args.into_iter().map(String::as_str);
+
+    while let Some(arg) = args.next() {
+        let arg: Vec<_> = arg.splitn(2, '=').collect();
+        if arg.get(0) != Some(&find_arg) {
+            continue;
+        }
+
+        let value = arg.get(1).cloned().or_else(|| args.next());
+        if value.as_ref().map_or(false, |p| pred(p)) {
+            return value;
+        }
+    }
+    None
+}
+
+#[test]
+fn test_arg_value() {
+    let args: Vec<_> = ["--bar=bar", "--foobar", "123", "--foo"]
+        .iter()
+        .map(|s| s.to_string())
+        .collect();
+
+    assert_eq!(arg_value(None, "--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);
+}
+
 #[allow(clippy::too_many_lines)]
 pub fn main() {
     rustc_driver::init_rustc_env_logger();
@@ -79,7 +119,7 @@ pub fn main() {
             // crate is
             // linted but not built
             let clippy_enabled = env::var("CLIPPY_TESTS").ok().map_or(false, |val| val == "true")
-                || orig_args.iter().any(|s| s == "--emit=dep-info,metadata");
+                || arg_value(&orig_args, "--emit", |val| val.split(',').any(|e| e == "metadata")).is_some();
 
             if clippy_enabled {
                 args.extend_from_slice(&["--cfg".to_owned(), r#"feature="cargo-clippy""#.to_owned()]);