about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbinarycat <binarycat@envs.net>2025-07-03 13:37:20 -0500
committerbinarycat <binarycat@envs.net>2025-07-08 16:16:11 -0500
commit9eb180541ac58409b1b2c82ad86e4078bcbb741b (patch)
tree16034d34848d22ef7c91766d2bceb683cee034e7
parent66bc2340876746365870a61b3ee3f769713c7525 (diff)
downloadrust-9eb180541ac58409b1b2c82ad86e4078bcbb741b.tar.gz
rust-9eb180541ac58409b1b2c82ad86e4078bcbb741b.zip
tidy: factor out change detection logic and make it more robust
now does proper parsing of git's output and falls back to
assuming all files are modified if `git` doesn't work.

accepts a closure so extensions can be checked.
-rw-r--r--src/tools/tidy/src/lib.rs26
-rw-r--r--src/tools/tidy/src/rustdoc_json.rs20
2 files changed, 30 insertions, 16 deletions
diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs
index 237737f0f16..90111079ecd 100644
--- a/src/tools/tidy/src/lib.rs
+++ b/src/tools/tidy/src/lib.rs
@@ -124,6 +124,32 @@ pub fn git_diff<S: AsRef<OsStr>>(base_commit: &str, extra_arg: S) -> Option<Stri
     Some(String::from_utf8_lossy(&output.stdout).into())
 }
 
+/// Returns true if any modified file matches the predicate, or if unable to list modified files.
+pub fn files_modified(base_commit: &str, pred: impl Fn(&str) -> bool) -> bool {
+    match crate::git_diff(&base_commit, "--name-status") {
+        Some(output) => {
+            let modified_files = output.lines().filter_map(|ln| {
+                let (status, name) = ln
+                    .trim_end()
+                    .split_once('\t')
+                    .expect("bad format from `git diff --name-status`");
+                if status == "M" { Some(name) } else { None }
+            });
+            for modified_file in modified_files {
+                if pred(modified_file) {
+                    return true;
+                }
+            }
+            false
+        }
+        None => {
+            eprintln!("warning: failed to run `git diff` to check for changes");
+            eprintln!("warning: assuming all files are modified");
+            true
+        }
+    }
+}
+
 pub mod alphabetical;
 pub mod bins;
 pub mod debug_artifacts;
diff --git a/src/tools/tidy/src/rustdoc_json.rs b/src/tools/tidy/src/rustdoc_json.rs
index dfbb35d69f1..da6f51c2a22 100644
--- a/src/tools/tidy/src/rustdoc_json.rs
+++ b/src/tools/tidy/src/rustdoc_json.rs
@@ -14,22 +14,10 @@ pub fn check(src_path: &Path, ci_info: &crate::CiInfo, bad: &mut bool) {
     };
 
     // First we check that `src/rustdoc-json-types` was modified.
-    match crate::git_diff(&base_commit, "--name-status") {
-        Some(output) => {
-            if !output
-                .lines()
-                .any(|line| line.starts_with("M") && line.contains(RUSTDOC_JSON_TYPES))
-            {
-                // `rustdoc-json-types` was not modified so nothing more to check here.
-                println!("`rustdoc-json-types` was not modified.");
-                return;
-            }
-        }
-        None => {
-            *bad = true;
-            eprintln!("error: failed to run `git diff` in rustdoc_json check");
-            return;
-        }
+    if !crate::files_modified(base_commit, |p| p == RUSTDOC_JSON_TYPES) {
+        // `rustdoc-json-types` was not modified so nothing more to check here.
+        println!("`rustdoc-json-types` was not modified.");
+        return;
     }
     // Then we check that if `FORMAT_VERSION` was updated, the `Latest feature:` was also updated.
     match crate::git_diff(&base_commit, src_path.join("rustdoc-json-types")) {