Skip to content

Commit 16398c3

Browse files
committed
Auto merge of #11235 - matthiaskrgr:rustc_in_ci, r=<try>
attempt to check rust-lang/rust with clippy in ci r? `@ghost` changelog: run clippy on rust-lang/rust as integration test
2 parents d446378 + 5d592ce commit 16398c3

File tree

2 files changed

+140
-0
lines changed

2 files changed

+140
-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: 139 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,137 @@ 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+
dbg!(&commit);
179+
// check out the commit in the rustc repo to ensure clippy is compatible
180+
181+
let st_git_checkout = Command::new("git")
182+
.arg("checkout")
183+
.arg(commit)
184+
.status()
185+
.current_dir("rust")
186+
.expect("git failed to check out commit");
187+
assert!(st_git_checkout.success());
188+
189+
let root_dir = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR"));
190+
let target_dir = std::path::Path::new(&root_dir).join("target");
191+
// let clippy_binary = target_dir.join(env!("PROFILE")).join(CARGO_CLIPPY);
192+
193+
// we need to make sure that `x.py clippy` picks up our self-built clippy
194+
// try to make the target dir discoverable as PATH
195+
196+
let path_env = target_dir.join(env!("PROFILE"));
197+
198+
let output = Command::new("x.py")
199+
.current_dir("rust")
200+
.env("RUST_BACKTRACE", "full")
201+
.env("PATH", path_env)
202+
.args(["clippy", "-Wclippy::pedantic", "-Wclippy::nursery"])
203+
.output()
204+
.expect("unable to run x.py clippy");
205+
206+
let stderr = String::from_utf8_lossy(&output.stderr);
207+
208+
// debug:
209+
eprintln!("{stderr}");
210+
211+
// this is an internal test to make sure we would correctly panic on a delay_span_bug
212+
if repo_name == "matthiaskrgr/clippy_ci_panic_test" {
213+
// we need to kind of switch around our logic here:
214+
// if we find a panic, everything is fine, if we don't panic, SOMETHING is broken about our testing
215+
216+
// the repo basically just contains a delay_span_bug that forces rustc/clippy to panic:
217+
/*
218+
#![feature(rustc_attrs)]
219+
#[rustc_error(delay_span_bug_from_inside_query)]
220+
fn main() {}
221+
*/
222+
223+
if stderr.find("error: internal compiler error").is_some() {
224+
eprintln!("we saw that we intentionally panicked, yay");
225+
return;
226+
}
227+
228+
panic!("panic caused by delay_span_bug was NOT detected! Something is broken!");
229+
}
230+
231+
if let Some(backtrace_start) = stderr.find("error: internal compiler error") {
232+
static BACKTRACE_END_MSG: &str = "end of query stack";
233+
let backtrace_end = stderr[backtrace_start..]
234+
.find(BACKTRACE_END_MSG)
235+
.expect("end of backtrace not found");
236+
237+
panic!(
238+
"internal compiler error\nBacktrace:\n\n{}",
239+
&stderr[backtrace_start..backtrace_start + backtrace_end + BACKTRACE_END_MSG.len()]
240+
);
241+
} else if stderr.contains("query stack during panic") {
242+
panic!("query stack during panic in the output");
243+
} else if stderr.contains("E0463") {
244+
// Encountering E0463 (can't find crate for `x`) did _not_ cause the build to fail in the
245+
// past. Even though it should have. That's why we explicitly panic here.
246+
// See PR #3552 and issue #3523 for more background.
247+
panic!("error: E0463");
248+
} else if stderr.contains("E0514") {
249+
panic!("incompatible crate versions");
250+
} else if stderr.contains("failed to run `rustc` to learn about target-specific information") {
251+
panic!("couldn't find librustc_driver, consider setting `LD_LIBRARY_PATH`");
252+
} else {
253+
assert!(
254+
!stderr.contains("toolchain") || !stderr.contains("is not installed"),
255+
"missing required toolchain"
256+
);
257+
}
258+
259+
match output.status.code() {
260+
Some(0) => println!("Compilation successful"),
261+
Some(code) => eprintln!("Compilation failed. Exit code: {code}"),
262+
None => panic!("Process terminated by signal"),
263+
}
264+
}

0 commit comments

Comments
 (0)