Skip to content

Commit 2546e6f

Browse files
committed
lintcheck: move out of clippy-dev into own crate
1 parent 99afc6e commit 2546e6f

File tree

8 files changed

+199
-59
lines changed

8 files changed

+199
-59
lines changed

.cargo/config

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[alias]
22
uitest = "test --test compile-test"
33
dev = "run --target-dir clippy_dev/target --package clippy_dev --bin clippy_dev --manifest-path clippy_dev/Cargo.toml --"
4-
dev-lintcheck = "run --target-dir clippy_dev/target --package clippy_dev --bin clippy_dev --manifest-path clippy_dev/Cargo.toml --features lintcheck -- lintcheck"
4+
dev-lintcheck = "run --target-dir lintcheck/target --package lintcheck --bin lintcheck --manifest-path lintcheck/Cargo.toml -- "
55

66
[build]
77
rustflags = ["-Zunstable-options"]

clippy_dev/Cargo.toml

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,20 +7,11 @@ edition = "2018"
77
[dependencies]
88
bytecount = "0.6"
99
clap = "2.33"
10-
flate2 = { version = "1.0.19", optional = true }
11-
fs_extra = { version = "1.2.0", optional = true }
1210
itertools = "0.9"
1311
opener = "0.4"
1412
regex = "1"
15-
serde = { version = "1.0", features = ["derive"], optional = true }
16-
serde_json = { version = "1.0", optional = true }
1713
shell-escape = "0.1"
18-
tar = { version = "0.4.30", optional = true }
19-
toml = { version = "0.5", optional = true }
20-
ureq = { version = "2.0.0-rc3", optional = true }
21-
rayon = { version = "1.5.0", optional = true }
2214
walkdir = "2"
2315

2416
[features]
25-
lintcheck = ["flate2", "serde_json", "tar", "toml", "ureq", "serde", "fs_extra", "rayon"]
2617
deny-warnings = []

clippy_dev/src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ use walkdir::WalkDir;
1212

1313
pub mod bless;
1414
pub mod fmt;
15-
pub mod lintcheck;
1615
pub mod new_lint;
1716
pub mod ra_setup;
1817
pub mod serve;

clippy_dev/src/main.rs

Lines changed: 3 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,13 @@
22

33
use clap::{App, Arg, ArgMatches, SubCommand};
44
use clippy_dev::{bless, fmt, new_lint, ra_setup, serve, stderr_length_check, update_lints};
5-
6-
#[cfg(feature = "lintcheck")]
7-
use clippy_dev::lintcheck;
8-
95
fn main() {
106
let matches = get_clap_config();
117

128
match matches.subcommand() {
139
("bless", Some(matches)) => {
1410
bless::bless(matches.is_present("ignore-timestamp"));
1511
},
16-
#[cfg(feature = "lintcheck")]
17-
("lintcheck", Some(matches)) => {
18-
lintcheck::run(&matches);
19-
},
2012
("fmt", Some(matches)) => {
2113
fmt::run(matches.is_present("check"), matches.is_present("verbose"));
2214
},
@@ -53,34 +45,7 @@ fn main() {
5345
}
5446

5547
fn get_clap_config<'a>() -> ArgMatches<'a> {
56-
#[cfg(feature = "lintcheck")]
57-
let lintcheck_sbcmd = SubCommand::with_name("lintcheck")
58-
.about("run clippy on a set of crates and check output")
59-
.arg(
60-
Arg::with_name("only")
61-
.takes_value(true)
62-
.value_name("CRATE")
63-
.long("only")
64-
.help("only process a single crate of the list"),
65-
)
66-
.arg(
67-
Arg::with_name("crates-toml")
68-
.takes_value(true)
69-
.value_name("CRATES-SOURCES-TOML-PATH")
70-
.long("crates-toml")
71-
.help("set the path for a crates.toml where lintcheck should read the sources from"),
72-
)
73-
.arg(
74-
Arg::with_name("threads")
75-
.takes_value(true)
76-
.value_name("N")
77-
.short("j")
78-
.long("jobs")
79-
.help("number of threads to use, 0 automatic choice"),
80-
)
81-
.arg(Arg::with_name("fix").help("runs cargo clippy --fix and checks if all suggestions apply"));
82-
83-
let app = App::new("Clippy developer tooling")
48+
App::new("Clippy developer tooling")
8449
.subcommand(
8550
SubCommand::with_name("bless")
8651
.about("bless the test output changes")
@@ -197,10 +162,6 @@ fn get_clap_config<'a>() -> ArgMatches<'a> {
197162
.validator_os(serve::validate_port),
198163
)
199164
.arg(Arg::with_name("lint").help("Which lint's page to load initially (optional)")),
200-
);
201-
202-
#[cfg(feature = "lintcheck")]
203-
let app = app.subcommand(lintcheck_sbcmd);
204-
205-
app.get_matches()
165+
)
166+
.get_matches()
206167
}

lintcheck/Cargo.toml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
[package]
2+
name = "lintcheck"
3+
version = "0.0.1"
4+
authors = ["Matthias Krüger <matthias.krueger@famsik.de>"]
5+
edition = "2018"
6+
7+
[dependencies]
8+
clap = "2.33"
9+
flate2 = {version = "1.0.19"}
10+
fs_extra = {version = "1.2.0"}
11+
rayon = {version = "1.5.0"}
12+
serde = {version = "1.0", features = ["derive"]}
13+
serde_json = {version = "1.0"}
14+
tar = {version = "0.4.30"}
15+
toml = {version = "0.5"}
16+
ureq = {version = "2.0.0-rc3"}
17+
18+
[features]
19+
deny-warnings = []

lintcheck/README.md

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
# Clippy Dev Tool
2+
3+
The Clippy Dev Tool is a tool to ease Clippy development, similar to `rustc`s
4+
`x.py`.
5+
6+
Functionalities (incomplete):
7+
8+
## `lintcheck`
9+
10+
Runs clippy on a fixed set of crates read from
11+
`clippy_dev/lintcheck_crates.toml` and saves logs of the lint warnings into the
12+
repo. We can then check the diff and spot new or disappearing warnings.
13+
14+
From the repo root, run:
15+
16+
```
17+
cargo run --target-dir clippy_dev/target --package clippy_dev \
18+
--bin clippy_dev --manifest-path clippy_dev/Cargo.toml --features lintcheck -- lintcheck
19+
```
20+
21+
or
22+
23+
```
24+
cargo dev-lintcheck
25+
```
26+
27+
By default the logs will be saved into
28+
`lintcheck-logs/lintcheck_crates_logs.txt`.
29+
30+
You can set a custom sources.toml by adding `--crates-toml custom.toml` or using
31+
`LINTCHECK_TOML="custom.toml"` where `custom.toml` must be a relative path from
32+
the repo root.
33+
34+
The results will then be saved to `lintcheck-logs/custom_logs.toml`.
35+
36+
### Configuring the Crate Sources
37+
38+
The sources to check are saved in a `toml` file. There are three types of
39+
sources.
40+
41+
1. Crates-io Source
42+
43+
```toml
44+
bitflags = {name = "bitflags", versions = ['1.2.1']}
45+
```
46+
Requires a "name" and one or multiple "versions" to be checked.
47+
48+
2. `git` Source
49+
````toml
50+
puffin = {name = "puffin", git_url = "https://github.com/EmbarkStudios/puffin", git_hash = "02dd4a3"}
51+
````
52+
Requires a name, the url to the repo and unique identifier of a commit,
53+
branch or tag which is checked out before linting. There is no way to always
54+
check `HEAD` because that would lead to changing lint-results as the repo
55+
would get updated. If `git_url` or `git_hash` is missing, an error will be
56+
thrown.
57+
58+
3. Local Dependency
59+
```toml
60+
clippy = {name = "clippy", path = "/home/user/clippy"}
61+
```
62+
For when you want to add a repository that is not published yet.
63+
64+
#### Command Line Options (optional)
65+
66+
```toml
67+
bitflags = {name = "bitflags", versions = ['1.2.1'], options = ['-Wclippy::pedantic', '-Wclippy::cargo']}
68+
```
69+
70+
It is possible to specify command line options for each crate. This makes it
71+
possible to only check a crate for certain lint groups. If no options are
72+
specified, the lint groups `clippy::all`, `clippy::pedantic`, and
73+
`clippy::cargo` are checked. If an empty array is specified only `clippy::all`
74+
is checked.
75+
76+
**Note:** `-Wclippy::all` is always enabled by default, unless `-Aclippy::all`
77+
is explicitly specified in the options.

lintcheck/lintcheck_crates.toml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
[crates]
2+
# some of these are from cargotest
3+
cargo = {name = "cargo", versions = ['0.49.0']}
4+
iron = {name = "iron", versions = ['0.6.1']}
5+
ripgrep = {name = "ripgrep", versions = ['12.1.1']}
6+
xsv = {name = "xsv", versions = ['0.13.0']}
7+
# commented out because of 173K clippy::match_same_arms msgs in language_type.rs
8+
#tokei = { name = "tokei", versions = ['12.0.4']}
9+
rayon = {name = "rayon", versions = ['1.5.0']}
10+
serde = {name = "serde", versions = ['1.0.118']}
11+
# top 10 crates.io dls
12+
bitflags = {name = "bitflags", versions = ['1.2.1']}
13+
# crash = {name = "clippy_crash", path = "/tmp/clippy_crash"}
14+
libc = {name = "libc", versions = ['0.2.81']}
15+
log = {name = "log", versions = ['0.4.11']}
16+
proc-macro2 = {name = "proc-macro2", versions = ['1.0.24']}
17+
quote = {name = "quote", versions = ['1.0.7']}
18+
rand = {name = "rand", versions = ['0.7.3']}
19+
rand_core = {name = "rand_core", versions = ['0.6.0']}
20+
regex = {name = "regex", versions = ['1.3.2']}
21+
syn = {name = "syn", versions = ['1.0.54']}
22+
unicode-xid = {name = "unicode-xid", versions = ['0.2.1']}
23+
# some more of dtolnays crates
24+
anyhow = {name = "anyhow", versions = ['1.0.38']}
25+
async-trait = {name = "async-trait", versions = ['0.1.42']}
26+
cxx = {name = "cxx", versions = ['1.0.32']}
27+
ryu = {name = "ryu", version = ['1.0.5']}
28+
serde_yaml = {name = "serde_yaml", versions = ['0.8.17']}
29+
thiserror = {name = "thiserror", versions = ['1.0.24']}
30+
# some embark crates, there are other interesting crates but
31+
# unfortunately adding them increases lintcheck runtime drastically
32+
cfg-expr = {name = "cfg-expr", versions = ['0.7.1']}
33+
puffin = {name = "puffin", git_url = "https://github.com/EmbarkStudios/puffin", git_hash = "02dd4a3"}
34+
rpmalloc = {name = "rpmalloc", versions = ['0.2.0']}
35+
tame-oidc = {name = "tame-oidc", versions = ['0.1.0']}

clippy_dev/src/lintcheck.rs renamed to lintcheck/src/main.rs

Lines changed: 64 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,11 @@
11
// Run clippy on a fixed set of crates and collect the warnings.
2-
// This helps observing the impact clippy changs have on a set of real-world code.
2+
// This helps observing the impact clippy changes have on a set of real-world code (and not just our testsuite).
33
//
44
// When a new lint is introduced, we can search the results for new warnings and check for false
55
// positives.
66

7-
#![cfg(feature = "lintcheck")]
87
#![allow(clippy::filter_map, clippy::collapsible_else_if)]
98

10-
use crate::clippy_project_root;
11-
129
use std::process::Command;
1310
use std::sync::atomic::{AtomicUsize, Ordering};
1411
use std::{collections::HashMap, io::ErrorKind};
@@ -18,7 +15,7 @@ use std::{
1815
path::{Path, PathBuf},
1916
};
2017

21-
use clap::ArgMatches;
18+
use clap::{App, Arg, ArgMatches, SubCommand};
2219
use rayon::prelude::*;
2320
use serde::{Deserialize, Serialize};
2421
use serde_json::Value;
@@ -564,7 +561,9 @@ fn lintcheck_needs_rerun(lintcheck_logs_path: &Path) -> bool {
564561
/// # Panics
565562
///
566563
/// This function panics if the clippy binaries don't exist.
567-
pub fn run(clap_config: &ArgMatches) {
564+
pub fn main() {
565+
let clap_config = &get_clap_config();
566+
568567
let config = LintcheckConfig::from_clap(clap_config);
569568

570569
println!("Compiling clippy...");
@@ -800,6 +799,65 @@ fn create_dirs(krate_download_dir: &Path, extract_dir: &Path) {
800799
});
801800
}
802801

802+
fn get_clap_config<'a>() -> ArgMatches<'a> {
803+
let lintcheck_sbcmd = SubCommand::with_name("lintcheck")
804+
.about("run clippy on a set of crates and check output")
805+
.arg(
806+
Arg::with_name("only")
807+
.takes_value(true)
808+
.value_name("CRATE")
809+
.long("only")
810+
.help("only process a single crate of the list"),
811+
)
812+
.arg(
813+
Arg::with_name("crates-toml")
814+
.takes_value(true)
815+
.value_name("CRATES-SOURCES-TOML-PATH")
816+
.long("crates-toml")
817+
.help("set the path for a crates.toml where lintcheck should read the sources from"),
818+
)
819+
.arg(
820+
Arg::with_name("threads")
821+
.takes_value(true)
822+
.value_name("N")
823+
.short("j")
824+
.long("jobs")
825+
.help("number of threads to use, 0 automatic choice"),
826+
)
827+
.arg(Arg::with_name("fix").help("runs cargo clippy --fix and checks if all suggestions apply"));
828+
829+
let app = App::new("Clippy developer tooling");
830+
831+
let app = app.subcommand(lintcheck_sbcmd);
832+
833+
app.get_matches()
834+
}
835+
836+
/// Returns the path to the Clippy project directory
837+
///
838+
/// # Panics
839+
///
840+
/// Panics if the current directory could not be retrieved, there was an error reading any of the
841+
/// Cargo.toml files or ancestor directory is the clippy root directory
842+
#[must_use]
843+
pub fn clippy_project_root() -> PathBuf {
844+
let current_dir = std::env::current_dir().unwrap();
845+
for path in current_dir.ancestors() {
846+
let result = std::fs::read_to_string(path.join("Cargo.toml"));
847+
if let Err(err) = &result {
848+
if err.kind() == std::io::ErrorKind::NotFound {
849+
continue;
850+
}
851+
}
852+
853+
let content = result.unwrap();
854+
if content.contains("[package]\nname = \"clippy\"") {
855+
return path.to_path_buf();
856+
}
857+
}
858+
panic!("error: Can't determine root of project. Please run inside a Clippy working dir.");
859+
}
860+
803861
#[test]
804862
fn lintcheck_test() {
805863
let args = [

0 commit comments

Comments
 (0)