diff options
| -rw-r--r-- | src/bootstrap/format.rs | 85 |
1 files changed, 70 insertions, 15 deletions
diff --git a/src/bootstrap/format.rs b/src/bootstrap/format.rs index b99bf33f482..985f34ff92f 100644 --- a/src/bootstrap/format.rs +++ b/src/bootstrap/format.rs @@ -1,7 +1,7 @@ //! Runs rustfmt on the repository. use crate::builder::Builder; -use crate::util::{output, t}; +use crate::util::{output, program_out_of_date, t}; use ignore::WalkBuilder; use std::collections::VecDeque; use std::path::{Path, PathBuf}; @@ -44,6 +44,68 @@ fn rustfmt(src: &Path, rustfmt: &Path, paths: &[PathBuf], check: bool) -> impl F } } +fn verify_timestamp(build: &Builder<'_>) -> bool { + let stamp_file = { + let mut s = build.out.clone(); + s.push("rustfmt.stamp"); + s + }; + + let mut cmd = Command::new(match build.initial_rustfmt() { + Some(p) => p, + None => return false, + }); + cmd.arg("--version"); + let output = match cmd.output() { + Ok(status) => status, + Err(_) => return false, + }; + if !output.status.success() { + return false; + } + let version = String::from_utf8(output.stdout).unwrap(); + !program_out_of_date(&stamp_file, &version) +} + +fn update_timestamp(build: &Builder<'_>) { + let stamp_file = { + let mut s = build.out.clone(); + s.push("rustfmt.stamp"); + s + }; + + let mut cmd = Command::new(match build.initial_rustfmt() { + Some(p) => p, + None => return, + }); + cmd.arg("--version"); + let output = match cmd.output() { + Ok(status) => status, + Err(_) => return, + }; + if !output.status.success() { + return; + } + let version = String::from_utf8(output.stdout).unwrap(); + + t!(std::fs::write(stamp_file, version)) +} + +fn get_modified_files(build: &Builder<'_>) -> Option<Vec<String>> { + let Ok(remote) = get_rust_lang_rust_remote() else {return None;}; + if !verify_timestamp(build) { + return None; + } + let base = + output(build.config.git().arg("merge-base").arg("HEAD").arg(format!("{remote}/master"))); + Some( + output(build.config.git().arg("diff").arg("--name-only").arg(base.trim())) + .lines() + .map(|s| s.trim().to_owned()) + .collect(), + ) +} + /// Finds the remote for rust-lang/rust. /// For example for these remotes it will return `upstream`. /// ```text @@ -140,20 +202,11 @@ pub fn format(build: &Builder<'_>, check: bool, paths: &[PathBuf]) { ignore_fmt.add(&format!("!/{}", untracked_path)).expect(&untracked_path); } if !check && paths.is_empty() { - let remote = t!(get_rust_lang_rust_remote()); - let base = output( - build - .config - .git() - .arg("merge-base") - .arg("HEAD") - .arg(format!("{remote}/master")), - ); - let files = - output(build.config.git().arg("diff").arg("--name-only").arg(base.trim())); - for file in files.lines() { - println!("formatting modified file {file}"); - ignore_fmt.add(&format!("/{file}")).expect(file); + if let Some(files) = get_modified_files(build) { + for file in files { + println!("formatting modified file {file}"); + ignore_fmt.add(&format!("/{file}")).expect(&file); + } } } } else { @@ -233,4 +286,6 @@ pub fn format(build: &Builder<'_>, check: bool, paths: &[PathBuf]) { drop(tx); thread.join().unwrap(); + + update_timestamp(build); } |
