Skip to content

Commit a1292be

Browse files
committed
attempt to run check rust-lang/rust with clippy in ci
r? @ghost
1 parent d446378 commit a1292be

File tree

2 files changed

+138
-0
lines changed

2 files changed

+138
-0
lines changed

.github/workflows/clippy_bors.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@ jobs:
203203
max-parallel: 6
204204
matrix:
205205
integration:
206+
- 'rust-lang/rust'
206207
- 'rust-lang/cargo'
207208
- 'rust-lang/chalk'
208209
- 'rust-lang/rustfmt'

tests/integration.rs

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ const CARGO_CLIPPY: &str = "cargo-clippy.exe";
2323
#[cfg_attr(feature = "integration", test)]
2424
fn integration_test() {
2525
let repo_name = env::var("INTEGRATION").expect("`INTEGRATION` var not set");
26+
27+
if repo_name == "rust-lang/rust" {
28+
return;
29+
}
30+
2631
let repo_url = format!("https://github.com/{repo_name}");
2732
let crate_name = repo_name
2833
.split('/')
@@ -123,3 +128,135 @@ fn integration_test() {
123128
None => panic!("Process terminated by signal"),
124129
}
125130
}
131+
132+
#[cfg_attr(feature = "integration", test)]
133+
fn integration_test_rustc() {
134+
let repo_name = env::var("INTEGRATION").expect("`INTEGRATION` var not set");
135+
136+
if repo_name != "rust-lang/rust" {
137+
return;
138+
}
139+
140+
let repo_url = format!("https://github.com/{repo_name}");
141+
let crate_name = repo_name
142+
.split('/')
143+
.nth(1)
144+
.expect("repo name should have format `<org>/<name>`");
145+
146+
let mut repo_dir = tempfile::tempdir().expect("couldn't create temp dir").into_path();
147+
repo_dir.push(crate_name);
148+
149+
let st_git_cl = Command::new("git")
150+
.args([
151+
OsStr::new("clone"),
152+
OsStr::new("--depth=5000"),
153+
OsStr::new(&repo_url),
154+
OsStr::new(&repo_dir),
155+
])
156+
.status()
157+
.expect("unable to run git");
158+
assert!(st_git_cl.success());
159+
160+
// clippy is pinned to a specific nightly version
161+
// check out the commit of that nightly to ensure compatibility
162+
let rustc_output = Command::new("rustc")
163+
.arg("--version")
164+
.arg("--verbose")
165+
.output()
166+
.expect("failed to run rustc --version");
167+
168+
let commit_line = String::from_utf8_lossy(rustc_output.stdout);
169+
let commit_line_ = commit_line
170+
.lines()
171+
.find(|line| line.starts_with("commit-hash: "))
172+
.expect("did not find 'commit-hash:' in --version output");
173+
174+
let commit = commit_line_
175+
.strip_prefix("commit-hash: ")
176+
.expect("failed parsing commit line");
177+
178+
// check out the commit in the rustc repo to ensure clippy is compatible
179+
180+
let st_git_checkout = Command::new("git")
181+
.arg("checkout")
182+
.arg(commit)
183+
.status()
184+
.expect("git failed to check out commit");
185+
assert!(st_git_checkout.success());
186+
187+
let root_dir = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR"));
188+
let target_dir = std::path::Path::new(&root_dir).join("target");
189+
let clippy_binary = target_dir.join(env!("PROFILE")).join(CARGO_CLIPPY);
190+
191+
// we need to make sure that `x.py clippy` picks up our self-built clippy
192+
// try to make the target dir discoverable as PATH
193+
194+
let path_env = target_dir.join(env!("PROFILE"));
195+
196+
let output = Command::new("x.py")
197+
.current_dir("rust")
198+
.env("RUST_BACKTRACE", "full")
199+
.env("PATH", path_env)
200+
.args(["clippy", "-Wclippy::pedantic", "-Wclippy::nursery"])
201+
.output()
202+
.expect("unable to run x.py clippy");
203+
204+
let stderr = String::from_utf8_lossy(&output.stderr);
205+
206+
// debug:
207+
eprintln!("{stderr}");
208+
209+
// this is an internal test to make sure we would correctly panic on a delay_span_bug
210+
if repo_name == "matthiaskrgr/clippy_ci_panic_test" {
211+
// we need to kind of switch around our logic here:
212+
// if we find a panic, everything is fine, if we don't panic, SOMETHING is broken about our testing
213+
214+
// the repo basically just contains a delay_span_bug that forces rustc/clippy to panic:
215+
/*
216+
#![feature(rustc_attrs)]
217+
#[rustc_error(delay_span_bug_from_inside_query)]
218+
fn main() {}
219+
*/
220+
221+
if stderr.find("error: internal compiler error").is_some() {
222+
eprintln!("we saw that we intentionally panicked, yay");
223+
return;
224+
}
225+
226+
panic!("panic caused by delay_span_bug was NOT detected! Something is broken!");
227+
}
228+
229+
if let Some(backtrace_start) = stderr.find("error: internal compiler error") {
230+
static BACKTRACE_END_MSG: &str = "end of query stack";
231+
let backtrace_end = stderr[backtrace_start..]
232+
.find(BACKTRACE_END_MSG)
233+
.expect("end of backtrace not found");
234+
235+
panic!(
236+
"internal compiler error\nBacktrace:\n\n{}",
237+
&stderr[backtrace_start..backtrace_start + backtrace_end + BACKTRACE_END_MSG.len()]
238+
);
239+
} else if stderr.contains("query stack during panic") {
240+
panic!("query stack during panic in the output");
241+
} else if stderr.contains("E0463") {
242+
// Encountering E0463 (can't find crate for `x`) did _not_ cause the build to fail in the
243+
// past. Even though it should have. That's why we explicitly panic here.
244+
// See PR #3552 and issue #3523 for more background.
245+
panic!("error: E0463");
246+
} else if stderr.contains("E0514") {
247+
panic!("incompatible crate versions");
248+
} else if stderr.contains("failed to run `rustc` to learn about target-specific information") {
249+
panic!("couldn't find librustc_driver, consider setting `LD_LIBRARY_PATH`");
250+
} else {
251+
assert!(
252+
!stderr.contains("toolchain") || !stderr.contains("is not installed"),
253+
"missing required toolchain"
254+
);
255+
}
256+
257+
match output.status.code() {
258+
Some(0) => println!("Compilation successful"),
259+
Some(code) => eprintln!("Compilation failed. Exit code: {code}"),
260+
None => panic!("Process terminated by signal"),
261+
}
262+
}

0 commit comments

Comments
 (0)