use crate::builder::Builder;
use crate::util::{output, program_out_of_date, t};
-use build_helper::git::get_rust_lang_rust_remote;
use ignore::WalkBuilder;
use std::collections::VecDeque;
use std::path::{Path, PathBuf};
///
/// Returns `None` if all files should be formatted.
fn get_modified_rs_files(build: &Builder<'_>) -> Option<Vec<String>> {
- let Ok(remote) = get_rust_lang_rust_remote() else {return None;};
+ let Ok(remote) = get_rust_lang_rust_remote() else { return None; };
if !verify_rustfmt_version(build) {
return None;
}
+
+ let merge_base =
+ output(build.config.git().arg("merge-base").arg(&format!("{remote}/master")).arg("HEAD"));
Some(
- output(
- build
- .config
- .git()
- .arg("diff-index")
- .arg("--name-only")
- .arg("--merge-base")
- .arg(&format!("{remote}/master")),
- )
- .lines()
- .map(|s| s.trim().to_owned())
- .filter(|f| Path::new(f).extension().map_or(false, |ext| ext == "rs"))
- .collect(),
+ output(build.config.git().arg("diff-index").arg("--name-only").arg(merge_base.trim()))
+ .lines()
+ .map(|s| s.trim().to_owned())
+ .filter(|f| Path::new(f).extension().map_or(false, |ext| ext == "rs"))
+ .collect(),
)
}
+/// 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>,