about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2021-03-06 10:06:52 +0100
committerMatthias Krüger <matthias.krueger@famsik.de>2021-03-11 13:26:26 +0100
commit2546e6f006da4acc79dbed3711674e7d7b73f1f0 (patch)
tree50c0205c8cf28c3819858d56cb7dc6fd19247929
parent99afc6e6ac2ce874c4fed32c083f1e160f533015 (diff)
downloadrust-2546e6f006da4acc79dbed3711674e7d7b73f1f0.tar.gz
rust-2546e6f006da4acc79dbed3711674e7d7b73f1f0.zip
lintcheck: move out of clippy-dev into own crate
-rw-r--r--.cargo/config2
-rw-r--r--clippy_dev/Cargo.toml9
-rw-r--r--clippy_dev/src/lib.rs1
-rw-r--r--clippy_dev/src/main.rs45
-rw-r--r--lintcheck/Cargo.toml19
-rw-r--r--lintcheck/README.md77
-rw-r--r--lintcheck/lintcheck_crates.toml35
-rw-r--r--lintcheck/src/main.rs (renamed from clippy_dev/src/lintcheck.rs)70
8 files changed, 199 insertions, 59 deletions
diff --git a/.cargo/config b/.cargo/config
index 1142cc470fe..ffa9a5bce85 100644
--- a/.cargo/config
+++ b/.cargo/config
@@ -1,7 +1,7 @@
 [alias]
 uitest = "test --test compile-test"
 dev = "run --target-dir clippy_dev/target --package clippy_dev --bin clippy_dev --manifest-path clippy_dev/Cargo.toml --"
-dev-lintcheck = "run --target-dir clippy_dev/target --package clippy_dev --bin clippy_dev --manifest-path clippy_dev/Cargo.toml --features lintcheck -- lintcheck"
+dev-lintcheck = "run --target-dir lintcheck/target --package lintcheck --bin lintcheck --manifest-path lintcheck/Cargo.toml  -- "
 
 [build]
 rustflags = ["-Zunstable-options"]
diff --git a/clippy_dev/Cargo.toml b/clippy_dev/Cargo.toml
index 5cfd5056f58..b1844e29b32 100644
--- a/clippy_dev/Cargo.toml
+++ b/clippy_dev/Cargo.toml
@@ -7,20 +7,11 @@ edition = "2018"
 [dependencies]
 bytecount = "0.6"
 clap = "2.33"
-flate2 = { version = "1.0.19", optional = true }
-fs_extra = { version = "1.2.0", optional = true }
 itertools = "0.9"
 opener = "0.4"
 regex = "1"
-serde = { version = "1.0", features = ["derive"], optional = true }
-serde_json = { version = "1.0", optional = true }
 shell-escape = "0.1"
-tar = { version = "0.4.30", optional = true }
-toml = { version = "0.5", optional = true }
-ureq = { version = "2.0.0-rc3", optional = true }
-rayon = { version = "1.5.0", optional = true }
 walkdir = "2"
 
 [features]
-lintcheck = ["flate2", "serde_json", "tar", "toml", "ureq", "serde", "fs_extra", "rayon"]
 deny-warnings = []
diff --git a/clippy_dev/src/lib.rs b/clippy_dev/src/lib.rs
index 0244ff2b6c2..a95abfaceaa 100644
--- a/clippy_dev/src/lib.rs
+++ b/clippy_dev/src/lib.rs
@@ -12,7 +12,6 @@ use walkdir::WalkDir;
 
 pub mod bless;
 pub mod fmt;
-pub mod lintcheck;
 pub mod new_lint;
 pub mod ra_setup;
 pub mod serve;
diff --git a/clippy_dev/src/main.rs b/clippy_dev/src/main.rs
index 33fef18d553..2a9f3e5348c 100644
--- a/clippy_dev/src/main.rs
+++ b/clippy_dev/src/main.rs
@@ -2,10 +2,6 @@
 
 use clap::{App, Arg, ArgMatches, SubCommand};
 use clippy_dev::{bless, fmt, new_lint, ra_setup, serve, stderr_length_check, update_lints};
-
-#[cfg(feature = "lintcheck")]
-use clippy_dev::lintcheck;
-
 fn main() {
     let matches = get_clap_config();
 
@@ -13,10 +9,6 @@ fn main() {
         ("bless", Some(matches)) => {
             bless::bless(matches.is_present("ignore-timestamp"));
         },
-        #[cfg(feature = "lintcheck")]
-        ("lintcheck", Some(matches)) => {
-            lintcheck::run(&matches);
-        },
         ("fmt", Some(matches)) => {
             fmt::run(matches.is_present("check"), matches.is_present("verbose"));
         },
@@ -53,34 +45,7 @@ fn main() {
 }
 
 fn get_clap_config<'a>() -> ArgMatches<'a> {
-    #[cfg(feature = "lintcheck")]
-    let lintcheck_sbcmd = SubCommand::with_name("lintcheck")
-        .about("run clippy on a set of crates and check output")
-        .arg(
-            Arg::with_name("only")
-                .takes_value(true)
-                .value_name("CRATE")
-                .long("only")
-                .help("only process a single crate of the list"),
-        )
-        .arg(
-            Arg::with_name("crates-toml")
-                .takes_value(true)
-                .value_name("CRATES-SOURCES-TOML-PATH")
-                .long("crates-toml")
-                .help("set the path for a crates.toml where lintcheck should read the sources from"),
-        )
-        .arg(
-            Arg::with_name("threads")
-                .takes_value(true)
-                .value_name("N")
-                .short("j")
-                .long("jobs")
-                .help("number of threads to use, 0 automatic choice"),
-        )
-        .arg(Arg::with_name("fix").help("runs cargo clippy --fix and checks if all suggestions apply"));
-
-    let app = App::new("Clippy developer tooling")
+    App::new("Clippy developer tooling")
         .subcommand(
             SubCommand::with_name("bless")
                 .about("bless the test output changes")
@@ -197,10 +162,6 @@ fn get_clap_config<'a>() -> ArgMatches<'a> {
                         .validator_os(serve::validate_port),
                 )
                 .arg(Arg::with_name("lint").help("Which lint's page to load initially (optional)")),
-        );
-
-    #[cfg(feature = "lintcheck")]
-    let app = app.subcommand(lintcheck_sbcmd);
-
-    app.get_matches()
+        )
+        .get_matches()
 }
diff --git a/lintcheck/Cargo.toml b/lintcheck/Cargo.toml
new file mode 100644
index 00000000000..071c1f89615
--- /dev/null
+++ b/lintcheck/Cargo.toml
@@ -0,0 +1,19 @@
+[package]
+name = "lintcheck"
+version = "0.0.1"
+authors = ["Matthias Krüger <matthias.krueger@famsik.de>"]
+edition = "2018"
+
+[dependencies]
+clap = "2.33"
+flate2 = {version = "1.0.19"}
+fs_extra = {version = "1.2.0"}
+rayon = {version = "1.5.0"}
+serde = {version = "1.0", features = ["derive"]}
+serde_json = {version = "1.0"}
+tar = {version = "0.4.30"}
+toml = {version = "0.5"}
+ureq = {version = "2.0.0-rc3"}
+
+[features]
+deny-warnings = []
diff --git a/lintcheck/README.md b/lintcheck/README.md
new file mode 100644
index 00000000000..a5ed9e27bd2
--- /dev/null
+++ b/lintcheck/README.md
@@ -0,0 +1,77 @@
+# Clippy Dev Tool
+
+The Clippy Dev Tool is a tool to ease Clippy development, similar to `rustc`s
+`x.py`.
+
+Functionalities (incomplete):
+
+## `lintcheck`
+
+Runs clippy on a fixed set of crates read from
+`clippy_dev/lintcheck_crates.toml` and saves logs of the lint warnings into the
+repo.  We can then check the diff and spot new or disappearing warnings.
+
+From the repo root, run:
+
+```
+cargo run --target-dir clippy_dev/target --package clippy_dev \
+--bin clippy_dev --manifest-path clippy_dev/Cargo.toml --features lintcheck -- lintcheck
+```
+
+or
+
+```
+cargo dev-lintcheck
+```
+
+By default the logs will be saved into
+`lintcheck-logs/lintcheck_crates_logs.txt`.
+
+You can set a custom sources.toml by adding `--crates-toml custom.toml` or using
+`LINTCHECK_TOML="custom.toml"` where `custom.toml` must be a relative path from
+the repo root.
+
+The results will then be saved to `lintcheck-logs/custom_logs.toml`.
+
+### Configuring the Crate Sources
+
+The sources to check are saved in a `toml` file. There are three types of
+sources.
+
+1. Crates-io Source
+
+   ```toml
+   bitflags = {name = "bitflags", versions = ['1.2.1']}
+   ```
+   Requires a "name" and one or multiple "versions" to be checked.
+
+2. `git` Source
+   ````toml
+   puffin = {name = "puffin", git_url = "https://github.com/EmbarkStudios/puffin", git_hash = "02dd4a3"}
+   ````
+   Requires a name, the url to the repo and unique identifier of a commit,
+   branch or tag which is checked out before linting.  There is no way to always
+   check `HEAD` because that would lead to changing lint-results as the repo
+   would get updated.  If `git_url` or `git_hash` is missing, an error will be
+   thrown.
+
+3. Local Dependency
+   ```toml
+   clippy = {name = "clippy", path = "/home/user/clippy"}
+   ```
+   For when you want to add a repository that is not published yet.
+
+#### Command Line Options (optional)
+
+```toml
+bitflags = {name = "bitflags", versions = ['1.2.1'], options = ['-Wclippy::pedantic', '-Wclippy::cargo']}
+```
+
+It is possible to specify command line options for each crate. This makes it
+possible to only check a crate for certain lint groups. If no options are
+specified, the lint groups `clippy::all`, `clippy::pedantic`, and
+`clippy::cargo` are checked. If an empty array is specified only `clippy::all`
+is checked.
+
+**Note:** `-Wclippy::all` is always enabled by default, unless `-Aclippy::all`
+is explicitly specified in the options.
diff --git a/lintcheck/lintcheck_crates.toml b/lintcheck/lintcheck_crates.toml
new file mode 100644
index 00000000000..dfee28f1a87
--- /dev/null
+++ b/lintcheck/lintcheck_crates.toml
@@ -0,0 +1,35 @@
+[crates]
+# some of these are from cargotest
+cargo = {name = "cargo", versions = ['0.49.0']}
+iron = {name = "iron", versions = ['0.6.1']}
+ripgrep = {name = "ripgrep", versions = ['12.1.1']}
+xsv = {name = "xsv", versions = ['0.13.0']}
+# commented out because of 173K clippy::match_same_arms msgs in language_type.rs
+#tokei = { name = "tokei", versions = ['12.0.4']}
+rayon = {name = "rayon", versions = ['1.5.0']}
+serde = {name = "serde", versions = ['1.0.118']}
+# top 10 crates.io dls
+bitflags = {name = "bitflags", versions = ['1.2.1']}
+# crash = {name = "clippy_crash", path = "/tmp/clippy_crash"}
+libc = {name = "libc", versions = ['0.2.81']}
+log = {name = "log", versions = ['0.4.11']}
+proc-macro2 = {name = "proc-macro2", versions = ['1.0.24']}
+quote = {name = "quote", versions = ['1.0.7']}
+rand = {name = "rand", versions = ['0.7.3']}
+rand_core = {name = "rand_core", versions = ['0.6.0']}
+regex = {name = "regex", versions = ['1.3.2']}
+syn = {name = "syn", versions = ['1.0.54']}
+unicode-xid = {name = "unicode-xid", versions = ['0.2.1']}
+# some more of dtolnays crates
+anyhow = {name = "anyhow", versions = ['1.0.38']}
+async-trait = {name = "async-trait", versions = ['0.1.42']}
+cxx = {name = "cxx", versions = ['1.0.32']}
+ryu = {name = "ryu", version = ['1.0.5']}
+serde_yaml = {name = "serde_yaml", versions = ['0.8.17']}
+thiserror = {name = "thiserror", versions = ['1.0.24']}
+# some embark crates, there are other interesting crates but
+# unfortunately adding them increases lintcheck runtime drastically
+cfg-expr = {name = "cfg-expr", versions = ['0.7.1']}
+puffin = {name = "puffin", git_url = "https://github.com/EmbarkStudios/puffin", git_hash = "02dd4a3"}
+rpmalloc = {name = "rpmalloc", versions = ['0.2.0']}
+tame-oidc = {name = "tame-oidc", versions = ['0.1.0']}
diff --git a/clippy_dev/src/lintcheck.rs b/lintcheck/src/main.rs
index 765d3349ec0..f5a54cfa8dc 100644
--- a/clippy_dev/src/lintcheck.rs
+++ b/lintcheck/src/main.rs
@@ -1,14 +1,11 @@
 // Run clippy on a fixed set of crates and collect the warnings.
-// This helps observing the impact clippy changs have on a set of real-world code.
+// This helps observing the impact clippy changes have on a set of real-world code (and not just our testsuite).
 //
 // When a new lint is introduced, we can search the results for new warnings and check for false
 // positives.
 
-#![cfg(feature = "lintcheck")]
 #![allow(clippy::filter_map, clippy::collapsible_else_if)]
 
-use crate::clippy_project_root;
-
 use std::process::Command;
 use std::sync::atomic::{AtomicUsize, Ordering};
 use std::{collections::HashMap, io::ErrorKind};
@@ -18,7 +15,7 @@ use std::{
     path::{Path, PathBuf},
 };
 
-use clap::ArgMatches;
+use clap::{App, Arg, ArgMatches, SubCommand};
 use rayon::prelude::*;
 use serde::{Deserialize, Serialize};
 use serde_json::Value;
@@ -564,7 +561,9 @@ fn lintcheck_needs_rerun(lintcheck_logs_path: &Path) -> bool {
 /// # Panics
 ///
 /// This function panics if the clippy binaries don't exist.
-pub fn run(clap_config: &ArgMatches) {
+pub fn main() {
+    let clap_config = &get_clap_config();
+
     let config = LintcheckConfig::from_clap(clap_config);
 
     println!("Compiling clippy...");
@@ -800,6 +799,65 @@ fn create_dirs(krate_download_dir: &Path, extract_dir: &Path) {
     });
 }
 
+fn get_clap_config<'a>() -> ArgMatches<'a> {
+    let lintcheck_sbcmd = SubCommand::with_name("lintcheck")
+        .about("run clippy on a set of crates and check output")
+        .arg(
+            Arg::with_name("only")
+                .takes_value(true)
+                .value_name("CRATE")
+                .long("only")
+                .help("only process a single crate of the list"),
+        )
+        .arg(
+            Arg::with_name("crates-toml")
+                .takes_value(true)
+                .value_name("CRATES-SOURCES-TOML-PATH")
+                .long("crates-toml")
+                .help("set the path for a crates.toml where lintcheck should read the sources from"),
+        )
+        .arg(
+            Arg::with_name("threads")
+                .takes_value(true)
+                .value_name("N")
+                .short("j")
+                .long("jobs")
+                .help("number of threads to use, 0 automatic choice"),
+        )
+        .arg(Arg::with_name("fix").help("runs cargo clippy --fix and checks if all suggestions apply"));
+
+    let app = App::new("Clippy developer tooling");
+
+    let app = app.subcommand(lintcheck_sbcmd);
+
+    app.get_matches()
+}
+
+/// Returns the path to the Clippy project directory
+///
+/// # Panics
+///
+/// Panics if the current directory could not be retrieved, there was an error reading any of the
+/// Cargo.toml files or ancestor directory is the clippy root directory
+#[must_use]
+pub fn clippy_project_root() -> PathBuf {
+    let current_dir = std::env::current_dir().unwrap();
+    for path in current_dir.ancestors() {
+        let result = std::fs::read_to_string(path.join("Cargo.toml"));
+        if let Err(err) = &result {
+            if err.kind() == std::io::ErrorKind::NotFound {
+                continue;
+            }
+        }
+
+        let content = result.unwrap();
+        if content.contains("[package]\nname = \"clippy\"") {
+            return path.to_path_buf();
+        }
+    }
+    panic!("error: Can't determine root of project. Please run inside a Clippy working dir.");
+}
+
 #[test]
 fn lintcheck_test() {
     let args = [