-# Clippy Dev Tool
+# Clippy Dev Tool
The Clippy Dev Tool is a tool to ease Clippy development, similar to `rustc`s `x.py`.
### Configuring the Crate Sources
-The sources to check are saved in a `toml` file.
-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.
+The sources to check are saved in a `toml` file.
+There are three types of sources.
-A 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.
-
-A local dependency:
-````toml
- clippy = {name = "clippy", path = "/home/user/clippy"}
-````
-For when you want to add a repository that is not published yet.
+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.
git_url: Option<String>,
git_hash: 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
/// Once processed (downloaded/extracted/cloned/copied...), this will be translated into a `Crate`
#[derive(Debug, Serialize, Deserialize, Eq, Hash, PartialEq)]
enum CrateSource {
- CratesIo { name: String, version: String },
- Git { name: String, url: String, commit: String },
- Path { name: String, path: PathBuf },
+ CratesIo {
+ name: String,
+ 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
name: String,
// path to the extracted sources that clippy can check
path: PathBuf,
+ options: Option<Vec<String>>,
}
/// A single warning that clippy issued while checking a `Crate`
/// copies a local folder
fn download_and_extract(&self) -> Crate {
match self {
- CrateSource::CratesIo { name, version } => {
+ CrateSource::CratesIo { name, version, options } => {
let extract_dir = PathBuf::from("target/lintcheck/crates");
let krate_download_dir = PathBuf::from("target/lintcheck/downloads");
version: version.clone(),
name: name.clone(),
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 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
version: commit.clone(),
name: name.clone(),
path: repo_path,
+ options: options.clone(),
}
},
- CrateSource::Path { name, path } => {
+ CrateSource::Path { name, path, options } => {
use fs_extra::dir;
// simply copy the entire directory into our target dir
version: String::from("local"),
name: name.clone(),
path: crate_root,
+ options: options.clone(),
}
},
}
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)
.env("CARGO_TARGET_DIR", shared_target_dir)
// lint warnings will look like this:
// src/cargo/ops/cargo_compile.rs:127:35: warning: usage of `FromIterator::from_iter`
- .args(&[
- "--",
- "--message-format=json",
- "--",
- "--cap-lints=warn",
- "-Wclippy::pedantic",
- "-Wclippy::cargo",
- ])
+ .args(&args)
.current_dir(&self.path)
.output()
.unwrap_or_else(|error| {
crate_sources.push(CrateSource::Path {
name: tk.name.clone(),
path: PathBuf::from(path),
+ options: tk.options.clone(),
});
}
crate_sources.push(CrateSource::CratesIo {
name: tk.name.clone(),
version: ver.to_string(),
+ options: tk.options.clone(),
});
})
}
name: tk.name.clone(),
url: tk.git_url.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