Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 5139104

Browse files
committedOct 22, 2020
Auto merge of #6188 - ebroto:primary_package, r=Manishearth
Add --no-deps option to avoid running on path dependencies in workspaces Since rust-lang/cargo#8758 has hit nightly, this allows us to address the second bullet point and [the concern related to `--fix`](rust-lang/cargo#8143 (comment)) in the [RUSTC_WORKSPACE_WRAPPER tracking issue](rust-lang/cargo#8143). As a reminder stabilizing that env var will solve #4612 (Clippy not running after `cargo check` in stable) and would allow to stabilize the `--fix` option in Clippy. changelog: Add `--no-deps` option to avoid running on path dependencies in workspaces Fixes #3025
2 parents fbe75a8 + 5f51eed commit 5139104

File tree

6 files changed

+120
-16
lines changed

6 files changed

+120
-16
lines changed
 

‎README.md

+16
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,22 @@ Note that this is still experimental and only supported on the nightly channel:
8888
cargo clippy --fix -Z unstable-options
8989
```
9090

91+
#### Workspaces
92+
93+
All the usual workspace options should work with Clippy. For example the following command
94+
will run Clippy on the `example` crate:
95+
96+
```terminal
97+
cargo clippy -p example
98+
```
99+
100+
As with `cargo check`, this includes dependencies that are members of the workspace, like path dependencies.
101+
If you want to run Clippy **only** on the given crate, use the `--no-deps` option like this:
102+
103+
```terminal
104+
cargo clippy -p example -- --no-deps
105+
```
106+
91107
### Running Clippy from the command line without installing it
92108

93109
To have cargo compile your crate with Clippy without Clippy installation
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[package]
2+
name = "path_dep"
3+
version = "0.1.0"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#![deny(clippy::empty_loop)]
2+
3+
#[cfg(feature = "primary_package_test")]
4+
pub fn lint_me() {
5+
loop {}
6+
}
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
[package]
22
name = "subcrate"
33
version = "0.1.0"
4+
5+
[dependencies]
6+
path_dep = { path = "../path_dep" }

‎src/driver.rs

+22-15
Original file line numberDiff line numberDiff line change
@@ -398,27 +398,34 @@ pub fn main() {
398398
args.extend(vec!["--sysroot".into(), sys_root]);
399399
};
400400

401+
let mut no_deps = false;
402+
let clippy_args = env::var("CLIPPY_ARGS")
403+
.unwrap_or_default()
404+
.split("__CLIPPY_HACKERY__")
405+
.filter_map(|s| match s {
406+
"" => None,
407+
"--no-deps" => {
408+
no_deps = true;
409+
None
410+
},
411+
_ => Some(s.to_string()),
412+
})
413+
.chain(vec!["--cfg".into(), r#"feature="cargo-clippy""#.into()])
414+
.collect::<Vec<String>>();
415+
401416
// this check ensures that dependencies are built but not linted and the final
402417
// crate is linted but not built
403-
let clippy_enabled = env::var("CLIPPY_TESTS").map_or(false, |val| val == "true")
404-
|| arg_value(&orig_args, "--cap-lints", |val| val == "allow").is_none();
405-
406-
if clippy_enabled {
407-
args.extend(vec!["--cfg".into(), r#"feature="cargo-clippy""#.into()]);
408-
if let Ok(extra_args) = env::var("CLIPPY_ARGS") {
409-
args.extend(extra_args.split("__CLIPPY_HACKERY__").filter_map(|s| {
410-
if s.is_empty() {
411-
None
412-
} else {
413-
Some(s.to_string())
414-
}
415-
}));
416-
}
418+
let clippy_disabled = env::var("CLIPPY_TESTS").map_or(false, |val| val != "true")
419+
|| arg_value(&orig_args, "--cap-lints", |val| val == "allow").is_some()
420+
|| no_deps && env::var("CARGO_PRIMARY_PACKAGE").is_err();
421+
422+
if !clippy_disabled {
423+
args.extend(clippy_args);
417424
}
418425
let mut clippy = ClippyCallbacks;
419426
let mut default = DefaultCallbacks;
420427
let callbacks: &mut (dyn rustc_driver::Callbacks + Send) =
421-
if clippy_enabled { &mut clippy } else { &mut default };
428+
if clippy_disabled { &mut default } else { &mut clippy };
422429
rustc_driver::RunCompiler::new(&args, callbacks).run()
423430
}))
424431
}

‎tests/dogfood.rs

+70-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
#![feature(once_cell)]
44

55
use std::lazy::SyncLazy;
6-
use std::path::PathBuf;
6+
use std::path::{Path, PathBuf};
77
use std::process::Command;
88

99
mod cargo;
@@ -41,12 +41,77 @@ fn dogfood_clippy() {
4141

4242
#[test]
4343
fn dogfood_subprojects() {
44+
fn test_no_deps_ignores_path_deps_in_workspaces() {
45+
fn clean(cwd: &Path, target_dir: &Path) {
46+
Command::new("cargo")
47+
.current_dir(cwd)
48+
.env("CARGO_TARGET_DIR", target_dir)
49+
.arg("clean")
50+
.args(&["-p", "subcrate"])
51+
.args(&["-p", "path_dep"])
52+
.output()
53+
.unwrap();
54+
}
55+
56+
if cargo::is_rustc_test_suite() {
57+
return;
58+
}
59+
let root = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
60+
let target_dir = root.join("target").join("dogfood");
61+
let cwd = root.join("clippy_workspace_tests");
62+
63+
// Make sure we start with a clean state
64+
clean(&cwd, &target_dir);
65+
66+
// `path_dep` is a path dependency of `subcrate` that would trigger a denied lint.
67+
// Make sure that with the `--no-deps` argument Clippy does not run on `path_dep`.
68+
let output = Command::new(&*CLIPPY_PATH)
69+
.current_dir(&cwd)
70+
.env("CLIPPY_DOGFOOD", "1")
71+
.env("CARGO_INCREMENTAL", "0")
72+
.arg("clippy")
73+
.args(&["-p", "subcrate"])
74+
.arg("--")
75+
.arg("--no-deps")
76+
.arg("-Cdebuginfo=0") // disable debuginfo to generate less data in the target dir
77+
.args(&["--cfg", r#"feature="primary_package_test""#])
78+
.output()
79+
.unwrap();
80+
println!("status: {}", output.status);
81+
println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
82+
println!("stderr: {}", String::from_utf8_lossy(&output.stderr));
83+
84+
assert!(output.status.success());
85+
86+
// Make sure we start with a clean state
87+
clean(&cwd, &target_dir);
88+
89+
// Test that without the `--no-deps` argument, `path_dep` is linted.
90+
let output = Command::new(&*CLIPPY_PATH)
91+
.current_dir(&cwd)
92+
.env("CLIPPY_DOGFOOD", "1")
93+
.env("CARGO_INCREMENTAL", "0")
94+
.arg("clippy")
95+
.args(&["-p", "subcrate"])
96+
.arg("--")
97+
.arg("-Cdebuginfo=0") // disable debuginfo to generate less data in the target dir
98+
.args(&["--cfg", r#"feature="primary_package_test""#])
99+
.output()
100+
.unwrap();
101+
println!("status: {}", output.status);
102+
println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
103+
println!("stderr: {}", String::from_utf8_lossy(&output.stderr));
104+
105+
assert!(!output.status.success());
106+
}
107+
44108
// run clippy on remaining subprojects and fail the test if lint warnings are reported
45109
if cargo::is_rustc_test_suite() {
46110
return;
47111
}
48112
let root_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
49113

114+
// NOTE: `path_dep` crate is omitted on purpose here
50115
for d in &[
51116
"clippy_workspace_tests",
52117
"clippy_workspace_tests/src",
@@ -72,4 +137,8 @@ fn dogfood_subprojects() {
72137

73138
assert!(output.status.success());
74139
}
140+
141+
// NOTE: Since tests run in parallel we can't run cargo commands on the same workspace at the
142+
// same time, so we test this immediately after the dogfood for workspaces.
143+
test_no_deps_ignores_path_deps_in_workspaces();
75144
}

0 commit comments

Comments
 (0)
Please sign in to comment.