Add command line options option to lintcheck crates config

This commit is contained in:
flip1995 2021-02-16 13:38:01 +01:00
parent e2753f9a7b
commit 2a28ea0bea
No known key found for this signature in database
GPG key ID: 1CA0DF2AF59D68A5
2 changed files with 78 additions and 35 deletions

View file

@ -1,4 +1,4 @@
# Clippy Dev Tool # Clippy Dev Tool
The Clippy Dev Tool is a tool to ease Clippy development, similar to `rustc`s `x.py`. The Clippy Dev Tool is a tool to ease Clippy development, similar to `rustc`s `x.py`.
@ -28,25 +28,39 @@ The results will then be saved to `lintcheck-logs/custom_logs.toml`.
### Configuring the Crate Sources ### Configuring the Crate Sources
The sources to check are saved in a `toml` file. The sources to check are saved in a `toml` file.
There are three types of sources. There are three types of sources.
A crates-io source:
````toml
bitflags = {name = "bitflags", versions = ['1.2.1']}
````
Requires a "name" and one or multiple "versions" to be checked.
A git source: 1. Crates-io 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.
A local dependency: ````toml
````toml bitflags = {name = "bitflags", versions = ['1.2.1']}
clippy = {name = "clippy", path = "/home/user/clippy"} ````
```` Requires a "name" and one or multiple "versions" to be checked.
For when you want to add a repository that is not published yet.
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.

View file

@ -32,15 +32,29 @@ struct TomlCrate {
git_url: Option<String>, git_url: Option<String>,
git_hash: Option<String>, git_hash: Option<String>,
path: Option<String>, path: Option<String>,
options: Option<Vec<String>>,
} }
/// Represents an archive we download from crates.io, or a git repo, or a local repo/folder /// Represents an archive we download from crates.io, or a git repo, or a local repo/folder
/// Once processed (downloaded/extracted/cloned/copied...), this will be translated into a `Crate` /// Once processed (downloaded/extracted/cloned/copied...), this will be translated into a `Crate`
#[derive(Debug, Serialize, Deserialize, Eq, Hash, PartialEq)] #[derive(Debug, Serialize, Deserialize, Eq, Hash, PartialEq)]
enum CrateSource { enum CrateSource {
CratesIo { name: String, version: String }, CratesIo {
Git { name: String, url: String, commit: String }, name: String,
Path { name: String, path: PathBuf }, version: String,
options: Option<Vec<String>>,
},
Git {
name: String,
url: String,
commit: String,
options: Option<Vec<String>>,
},
Path {
name: String,
path: PathBuf,
options: Option<Vec<String>>,
},
} }
/// Represents the actual source code of a crate that we ran "cargo clippy" on /// Represents the actual source code of a crate that we ran "cargo clippy" on
@ -50,6 +64,7 @@ struct Crate {
name: String, name: String,
// path to the extracted sources that clippy can check // path to the extracted sources that clippy can check
path: PathBuf, path: PathBuf,
options: Option<Vec<String>>,
} }
/// A single warning that clippy issued while checking a `Crate` /// A single warning that clippy issued while checking a `Crate`
@ -81,7 +96,7 @@ impl CrateSource {
/// copies a local folder /// copies a local folder
fn download_and_extract(&self) -> Crate { fn download_and_extract(&self) -> Crate {
match self { match self {
CrateSource::CratesIo { name, version } => { CrateSource::CratesIo { name, version, options } => {
let extract_dir = PathBuf::from("target/lintcheck/crates"); let extract_dir = PathBuf::from("target/lintcheck/crates");
let krate_download_dir = PathBuf::from("target/lintcheck/downloads"); let krate_download_dir = PathBuf::from("target/lintcheck/downloads");
@ -113,9 +128,15 @@ impl CrateSource {
version: version.clone(), version: version.clone(),
name: name.clone(), name: name.clone(),
path: extract_dir.join(format!("{}-{}/", name, version)), path: extract_dir.join(format!("{}-{}/", name, version)),
options: options.clone(),
} }
}, },
CrateSource::Git { name, url, commit } => { CrateSource::Git {
name,
url,
commit,
options,
} => {
let repo_path = { let repo_path = {
let mut repo_path = PathBuf::from("target/lintcheck/crates"); let mut repo_path = PathBuf::from("target/lintcheck/crates");
// add a -git suffix in case we have the same crate from crates.io and a git repo // add a -git suffix in case we have the same crate from crates.io and a git repo
@ -152,9 +173,10 @@ impl CrateSource {
version: commit.clone(), version: commit.clone(),
name: name.clone(), name: name.clone(),
path: repo_path, path: repo_path,
options: options.clone(),
} }
}, },
CrateSource::Path { name, path } => { CrateSource::Path { name, path, options } => {
use fs_extra::dir; use fs_extra::dir;
// simply copy the entire directory into our target dir // simply copy the entire directory into our target dir
@ -183,6 +205,7 @@ impl CrateSource {
version: String::from("local"), version: String::from("local"),
name: name.clone(), name: name.clone(),
path: crate_root, path: crate_root,
options: options.clone(),
} }
}, },
} }
@ -198,18 +221,21 @@ impl Crate {
let shared_target_dir = clippy_project_root().join("target/lintcheck/shared_target_dir/"); let shared_target_dir = clippy_project_root().join("target/lintcheck/shared_target_dir/");
let mut args = vec!["--", "--message-format=json", "--", "--cap-lints=warn"];
if let Some(options) = &self.options {
for opt in options {
args.push(opt);
}
} else {
args.extend(&["-Wclippy::pedantic", "-Wclippy::cargo"])
}
let all_output = std::process::Command::new(&cargo_clippy_path) let all_output = std::process::Command::new(&cargo_clippy_path)
.env("CARGO_TARGET_DIR", shared_target_dir) .env("CARGO_TARGET_DIR", shared_target_dir)
// lint warnings will look like this: // lint warnings will look like this:
// src/cargo/ops/cargo_compile.rs:127:35: warning: usage of `FromIterator::from_iter` // src/cargo/ops/cargo_compile.rs:127:35: warning: usage of `FromIterator::from_iter`
.args(&[ .args(&args)
"--",
"--message-format=json",
"--",
"--cap-lints=warn",
"-Wclippy::pedantic",
"-Wclippy::cargo",
])
.current_dir(&self.path) .current_dir(&self.path)
.output() .output()
.unwrap_or_else(|error| { .unwrap_or_else(|error| {
@ -289,6 +315,7 @@ fn read_crates(toml_path: Option<&str>) -> (String, Vec<CrateSource>) {
crate_sources.push(CrateSource::Path { crate_sources.push(CrateSource::Path {
name: tk.name.clone(), name: tk.name.clone(),
path: PathBuf::from(path), path: PathBuf::from(path),
options: tk.options.clone(),
}); });
} }
@ -298,6 +325,7 @@ fn read_crates(toml_path: Option<&str>) -> (String, Vec<CrateSource>) {
crate_sources.push(CrateSource::CratesIo { crate_sources.push(CrateSource::CratesIo {
name: tk.name.clone(), name: tk.name.clone(),
version: ver.to_string(), version: ver.to_string(),
options: tk.options.clone(),
}); });
}) })
} }
@ -307,6 +335,7 @@ fn read_crates(toml_path: Option<&str>) -> (String, Vec<CrateSource>) {
name: tk.name.clone(), name: tk.name.clone(),
url: tk.git_url.clone().unwrap(), url: tk.git_url.clone().unwrap(),
commit: tk.git_hash.clone().unwrap(), commit: tk.git_hash.clone().unwrap(),
options: tk.options.clone(),
}); });
} }
// if we have a version as well as a git data OR only one git data, something is funky // if we have a version as well as a git data OR only one git data, something is funky