]> git.lizzy.rs Git - rust.git/blob - tests/dogfood.rs
Remove author requirement for `cargo_common_metadata`
[rust.git] / tests / dogfood.rs
1 // Dogfood cannot run on Windows
2 #![cfg(not(windows))]
3 #![feature(once_cell)]
4
5 use std::lazy::SyncLazy;
6 use std::path::PathBuf;
7 use std::process::Command;
8
9 mod cargo;
10
11 static CLIPPY_PATH: SyncLazy<PathBuf> = SyncLazy::new(|| cargo::TARGET_LIB.join("cargo-clippy"));
12
13 #[test]
14 fn dogfood_clippy() {
15     // run clippy on itself and fail the test if lint warnings are reported
16     if cargo::is_rustc_test_suite() {
17         return;
18     }
19     let root_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
20
21     let mut command = Command::new(&*CLIPPY_PATH);
22     command
23         .current_dir(root_dir)
24         .env("CLIPPY_DOGFOOD", "1")
25         .env("CARGO_INCREMENTAL", "0")
26         .arg("clippy")
27         .arg("--all-targets")
28         .arg("--all-features")
29         .arg("--")
30         .args(&["-D", "clippy::all"])
31         .args(&["-D", "clippy::pedantic"])
32         .arg("-Cdebuginfo=0"); // disable debuginfo to generate less data in the target dir
33
34     // internal lints only exist if we build with the internal-lints feature
35     if cfg!(feature = "internal-lints") {
36         command.args(&["-D", "clippy::internal"]);
37     }
38
39     let output = command.output().unwrap();
40
41     println!("status: {}", output.status);
42     println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
43     println!("stderr: {}", String::from_utf8_lossy(&output.stderr));
44
45     assert!(output.status.success());
46 }
47
48 fn test_no_deps_ignores_path_deps_in_workspaces() {
49     if cargo::is_rustc_test_suite() {
50         return;
51     }
52     let root = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
53     let target_dir = root.join("target").join("dogfood");
54     let cwd = root.join("clippy_workspace_tests");
55
56     // Make sure we start with a clean state
57     Command::new("cargo")
58         .current_dir(&cwd)
59         .env("CARGO_TARGET_DIR", &target_dir)
60         .arg("clean")
61         .args(&["-p", "subcrate"])
62         .args(&["-p", "path_dep"])
63         .output()
64         .unwrap();
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     let lint_path_dep = || {
87         // Test that without the `--no-deps` argument, `path_dep` is linted.
88         let output = Command::new(&*CLIPPY_PATH)
89             .current_dir(&cwd)
90             .env("CLIPPY_DOGFOOD", "1")
91             .env("CARGO_INCREMENTAL", "0")
92             .arg("clippy")
93             .args(&["-p", "subcrate"])
94             .arg("--")
95             .arg("-Cdebuginfo=0") // disable debuginfo to generate less data in the target dir
96             .args(&["--cfg", r#"feature="primary_package_test""#])
97             .output()
98             .unwrap();
99         println!("status: {}", output.status);
100         println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
101         println!("stderr: {}", String::from_utf8_lossy(&output.stderr));
102
103         assert!(!output.status.success());
104         assert!(
105             String::from_utf8(output.stderr)
106                 .unwrap()
107                 .contains("error: empty `loop {}` wastes CPU cycles")
108         );
109     };
110
111     // Make sure Cargo is aware of the removal of `--no-deps`.
112     lint_path_dep();
113
114     let successful_build = || {
115         let output = Command::new(&*CLIPPY_PATH)
116             .current_dir(&cwd)
117             .env("CLIPPY_DOGFOOD", "1")
118             .env("CARGO_INCREMENTAL", "0")
119             .arg("clippy")
120             .args(&["-p", "subcrate"])
121             .arg("--")
122             .arg("-Cdebuginfo=0") // disable debuginfo to generate less data in the target dir
123             .output()
124             .unwrap();
125         println!("status: {}", output.status);
126         println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
127         println!("stderr: {}", String::from_utf8_lossy(&output.stderr));
128
129         assert!(output.status.success());
130
131         output
132     };
133
134     // Trigger a sucessful build, so Cargo would like to cache the build result.
135     successful_build();
136
137     // Make sure there's no spurious rebuild when nothing changes.
138     let stderr = String::from_utf8(successful_build().stderr).unwrap();
139     assert!(!stderr.contains("Compiling"));
140     assert!(!stderr.contains("Checking"));
141     assert!(stderr.contains("Finished"));
142
143     // Make sure Cargo is aware of the new `--cfg` flag.
144     lint_path_dep();
145 }
146
147 #[test]
148 fn dogfood_subprojects() {
149     // run clippy on remaining subprojects and fail the test if lint warnings are reported
150     if cargo::is_rustc_test_suite() {
151         return;
152     }
153     let root_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
154
155     // NOTE: `path_dep` crate is omitted on purpose here
156     for d in &[
157         "clippy_workspace_tests",
158         "clippy_workspace_tests/src",
159         "clippy_workspace_tests/subcrate",
160         "clippy_workspace_tests/subcrate/src",
161         "clippy_dev",
162         "clippy_lints",
163         "clippy_utils",
164         "rustc_tools_util",
165     ] {
166         let mut command = Command::new(&*CLIPPY_PATH);
167         command
168             .current_dir(root_dir.join(d))
169             .env("CLIPPY_DOGFOOD", "1")
170             .env("CARGO_INCREMENTAL", "0")
171             .arg("clippy")
172             .arg("--all-targets")
173             .arg("--all-features")
174             .arg("--")
175             .args(&["-D", "clippy::all"])
176             .args(&["-D", "clippy::pedantic"])
177             .arg("-Cdebuginfo=0"); // disable debuginfo to generate less data in the target dir
178
179         // internal lints only exist if we build with the internal-lints feature
180         if cfg!(feature = "internal-lints") {
181             command.args(&["-D", "clippy::internal"]);
182         }
183
184         let output = command.output().unwrap();
185
186         println!("status: {}", output.status);
187         println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
188         println!("stderr: {}", String::from_utf8_lossy(&output.stderr));
189
190         assert!(output.status.success());
191     }
192
193     // NOTE: Since tests run in parallel we can't run cargo commands on the same workspace at the
194     // same time, so we test this immediately after the dogfood for workspaces.
195     test_no_deps_ignores_path_deps_in_workspaces();
196 }