about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--lintcheck/src/main.rs40
1 files changed, 38 insertions, 2 deletions
diff --git a/lintcheck/src/main.rs b/lintcheck/src/main.rs
index 8d0d41ab945..ab86f6ad6f9 100644
--- a/lintcheck/src/main.rs
+++ b/lintcheck/src/main.rs
@@ -120,14 +120,16 @@ impl Crate {
 
         if config.perf {
             cmd = Command::new("perf");
+            let perf_data_filename = get_perf_data_filename(&self.path);
             cmd.args(&[
                 "record",
                 "-e",
                 "instructions", // Only count instructions
                 "-g",           // Enable call-graph, useful for flamegraphs and produces richer reports
                 "--quiet",      // Do not tamper with lintcheck's normal output
+                "--compression-level=22",
                 "-o",
-                "perf.data",
+                &perf_data_filename,
                 "--",
                 "cargo",
             ]);
@@ -165,7 +167,7 @@ impl Crate {
             return Vec::new();
         }
 
-        if !config.fix {
+        if !config.fix && !config.perf {
             cmd.arg("--message-format=json");
         }
 
@@ -203,6 +205,11 @@ impl Crate {
             return Vec::new();
         }
 
+        // We don't want to keep target directories if benchmarking
+        if config.perf {
+            let _ = fs::remove_dir_all(&shared_target_dir);
+        }
+
         // get all clippy warnings and ICEs
         let mut entries: Vec<ClippyCheckOutput> = Message::parse_stream(stdout.as_bytes())
             .filter_map(|msg| match msg {
@@ -441,6 +448,35 @@ fn lintcheck(config: LintcheckConfig) {
     fs::write(&config.lintcheck_results_path, text).unwrap();
 }
 
+/// Traverse a directory looking for `perf.data.<number>` files, and adds one
+/// to the most recent of those files, returning the new most recent `perf.data`
+/// file name.
+fn get_perf_data_filename(source_path: &Path) -> String {
+    if source_path.join("perf.data").exists() {
+        let mut max_number = 0;
+        fs::read_dir(source_path)
+            .unwrap()
+            .filter_map(Result::ok)
+            .filter(|path| {
+                path.file_name()
+                    .as_os_str()
+                    .to_string_lossy() // We don't care about data loss, as we're checking for equality
+                    .starts_with("perf.data")
+            })
+            .for_each(|path| {
+                let file_name = path.file_name();
+                let file_name = file_name.as_os_str().to_str().unwrap().split('.').next_back().unwrap();
+                if let Ok(parsed_file_name) = file_name.parse::<usize>() {
+                    if parsed_file_name >= max_number {
+                        max_number = parsed_file_name + 1;
+                    }
+                }
+            });
+        return format!("perf.data.{max_number}");
+    }
+    String::from("perf.data")
+}
+
 /// Returns the path to the Clippy project directory
 #[must_use]
 fn clippy_project_root() -> &'static Path {