Skip to content

Commit 01ea926

Browse files
committed
Lintcheck: Normalize thread IDs in shared_target_dir
1 parent 796ade6 commit 01ea926

File tree

1 file changed

+44
-5
lines changed

1 file changed

+44
-5
lines changed

lintcheck/src/main.rs

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,6 @@ impl Crate {
8787
);
8888
}
8989

90-
let shared_target_dir = clippy_project_root().join("target/lintcheck/shared_target_dir");
91-
9290
let cargo_home = env!("CARGO_HOME");
9391

9492
// `src/lib.rs` -> `target/lintcheck/sources/crate-1.2.3/src/lib.rs`
@@ -132,7 +130,7 @@ impl Crate {
132130
// The wrapper is set to `lintcheck` itself so we can force enable linting and ignore certain crates
133131
// (see `crate::driver`)
134132
let status = cmd
135-
.env("CARGO_TARGET_DIR", shared_target_dir.join("recursive"))
133+
.env("CARGO_TARGET_DIR", shared_target_dir("recursive"))
136134
.env("RUSTC_WRAPPER", env::current_exe().unwrap())
137135
// Pass the absolute path so `crate::driver` can find `clippy-driver`, as it's executed in various
138136
// different working directories
@@ -150,9 +148,10 @@ impl Crate {
150148
cmd.arg("--message-format=json");
151149
}
152150

151+
let shared_target_dir = shared_target_dir(&format!("_{thread_index:?}"));
153152
let all_output = cmd
154153
// use the looping index to create individual target dirs
155-
.env("CARGO_TARGET_DIR", shared_target_dir.join(format!("_{thread_index:?}")))
154+
.env("CARGO_TARGET_DIR", shared_target_dir.as_os_str())
156155
// Roughly equivalent to `cargo clippy`/`cargo clippy --fix`
157156
.env("RUSTC_WORKSPACE_WRAPPER", clippy_driver_path)
158157
.output()
@@ -186,7 +185,10 @@ impl Crate {
186185
// get all clippy warnings and ICEs
187186
let mut entries: Vec<ClippyCheckOutput> = Message::parse_stream(stdout.as_bytes())
188187
.filter_map(|msg| match msg {
189-
Ok(Message::CompilerMessage(message)) => ClippyWarning::new(message.message, &self.base_url),
188+
Ok(Message::CompilerMessage(message)) => ClippyWarning::new(
189+
normalize_diag(message.message, shared_target_dir.to_str().unwrap()),
190+
&self.base_url,
191+
),
190192
_ => None,
191193
})
192194
.map(ClippyCheckOutput::ClippyWarning)
@@ -202,6 +204,34 @@ impl Crate {
202204
}
203205
}
204206

207+
/// The target directory can sometimes be stored in the file name of spans.
208+
/// This is problematic since the directory in constructed from the thread
209+
/// ID and also used in our CI to determine if two lint emissions are the
210+
/// same or not. This function simply normalizes the `_<thread_id>` to `_*`.
211+
fn normalize_diag(
212+
mut message: cargo_metadata::diagnostic::Diagnostic,
213+
thread_target_dir: &str,
214+
) -> cargo_metadata::diagnostic::Diagnostic {
215+
let mut dir_found = false;
216+
message
217+
.spans
218+
.iter_mut()
219+
.filter(|span| span.file_name.starts_with(thread_target_dir))
220+
.for_each(|span| {
221+
dir_found = true;
222+
span.file_name
223+
.replace_range(0..thread_target_dir.len(), shared_target_dir("_*").to_str().unwrap());
224+
});
225+
226+
if dir_found {
227+
message
228+
.rendered
229+
.as_mut()
230+
.map(|rendered| *rendered = rendered.replace(thread_target_dir, shared_target_dir("_*").to_str().unwrap()));
231+
}
232+
message
233+
}
234+
205235
/// Builds clippy inside the repo to make sure we have a clippy executable we can use.
206236
fn build_clippy() -> String {
207237
let output = Command::new("cargo")
@@ -388,6 +418,15 @@ fn clippy_project_root() -> &'static Path {
388418
Path::new(env!("CARGO_MANIFEST_DIR")).parent().unwrap()
389419
}
390420

421+
/// The qualifier can be used to separate different threads from another. By
422+
/// default it should be set to `_<thread_id>`
423+
#[must_use]
424+
fn shared_target_dir(qualifier: &str) -> PathBuf {
425+
clippy_project_root()
426+
.join("target/lintcheck/shared_target_dir")
427+
.join(qualifier)
428+
}
429+
391430
#[test]
392431
fn lintcheck_test() {
393432
let args = [

0 commit comments

Comments
 (0)