Skip to content

Commit

Permalink
Format only modified files
Browse files Browse the repository at this point in the history
As discussed on rust-lang#105688, this makes x fmt only format modified files
  • Loading branch information
albertlarsan68 committed Dec 27, 2022
1 parent a1fc711 commit 633a6c8
Showing 1 changed file with 46 additions and 0 deletions.
46 changes: 46 additions & 0 deletions src/bootstrap/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,35 @@ fn rustfmt(src: &Path, rustfmt: &Path, paths: &[PathBuf], check: bool) -> impl F
}
}

/// Finds the remote for rust-lang/rust.
/// For example for these remotes it will return `upstream`.
/// ```text
/// origin https://github.com/Nilstrieb/rust.git (fetch)
/// origin https://github.com/Nilstrieb/rust.git (push)
/// upstream https://github.com/rust-lang/rust (fetch)
/// upstream https://github.com/rust-lang/rust (push)
/// ```
fn get_rust_lang_rust_remote() -> Result<String, String> {
let mut git = Command::new("git");
git.args(["config", "--local", "--get-regex", "remote\\..*\\.url"]);

let output = git.output().map_err(|err| format!("{err:?}"))?;
if !output.status.success() {
return Err("failed to execute git config command".to_owned());
}

let stdout = String::from_utf8(output.stdout).map_err(|err| format!("{err:?}"))?;

let rust_lang_remote = stdout
.lines()
.find(|remote| remote.contains("rust-lang"))
.ok_or_else(|| "rust-lang/rust remote not found".to_owned())?;

let remote_name =
rust_lang_remote.split('.').nth(1).ok_or_else(|| "remote name not found".to_owned())?;
Ok(remote_name.into())
}

#[derive(serde::Deserialize)]
struct RustfmtConfig {
ignore: Vec<String>,
Expand Down Expand Up @@ -110,6 +139,23 @@ pub fn format(build: &Builder<'_>, check: bool, paths: &[PathBuf]) {
// preventing the latter from being formatted.
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);
}
}
} else {
println!("Not in git tree. Skipping git-aware format checks");
}
Expand Down

0 comments on commit 633a6c8

Please sign in to comment.