summaryrefslogtreecommitdiffstats
path: root/src/bootstrap/format.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/bootstrap/format.rs')
-rw-r--r--src/bootstrap/format.rs60
1 files changed, 42 insertions, 18 deletions
diff --git a/src/bootstrap/format.rs b/src/bootstrap/format.rs
index bfc57a85c..6d5753e8a 100644
--- a/src/bootstrap/format.rs
+++ b/src/bootstrap/format.rs
@@ -1,8 +1,8 @@
//! Runs rustfmt on the repository.
use crate::builder::Builder;
-use crate::util::{output, output_result, program_out_of_date, t};
-use build_helper::git::updated_master_branch;
+use crate::util::{output, program_out_of_date, t};
+use build_helper::git::get_git_modified_files;
use ignore::WalkBuilder;
use std::collections::VecDeque;
use std::path::{Path, PathBuf};
@@ -80,26 +80,14 @@ fn update_rustfmt_version(build: &Builder<'_>) {
///
/// Returns `None` if all files should be formatted.
fn get_modified_rs_files(build: &Builder<'_>) -> Result<Option<Vec<String>>, String> {
- let Ok(updated_master) = updated_master_branch(Some(&build.config.src)) else { return Ok(None); };
-
if !verify_rustfmt_version(build) {
return Ok(None);
}
- let merge_base =
- output_result(build.config.git().arg("merge-base").arg(&updated_master).arg("HEAD"))?;
- Ok(Some(
- output_result(
- 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(),
- ))
+ get_git_modified_files(Some(&build.config.src), &vec!["rs"])
}
-#[derive(serde::Deserialize)]
+#[derive(serde_derive::Deserialize)]
struct RustfmtConfig {
ignore: Vec<String>,
}
@@ -205,10 +193,46 @@ pub fn format(build: &Builder<'_>, check: bool, paths: &[PathBuf]) {
let (tx, rx): (SyncSender<PathBuf>, _) = std::sync::mpsc::sync_channel(128);
let walker = match paths.get(0) {
Some(first) => {
- let mut walker = WalkBuilder::new(first);
+ let find_shortcut_candidates = |p: &PathBuf| {
+ let mut candidates = Vec::new();
+ for candidate in WalkBuilder::new(src.clone()).max_depth(Some(3)).build() {
+ if let Ok(entry) = candidate {
+ if let Some(dir_name) = p.file_name() {
+ if entry.path().is_dir() && entry.file_name() == dir_name {
+ candidates.push(entry.into_path());
+ }
+ }
+ }
+ }
+ candidates
+ };
+
+ // Only try to look for shortcut candidates for single component paths like
+ // `std` and not for e.g. relative paths like `../library/std`.
+ let should_look_for_shortcut_dir = |p: &PathBuf| p.components().count() == 1;
+
+ let mut walker = if should_look_for_shortcut_dir(first) {
+ if let [single_candidate] = &find_shortcut_candidates(first)[..] {
+ WalkBuilder::new(single_candidate)
+ } else {
+ WalkBuilder::new(first)
+ }
+ } else {
+ WalkBuilder::new(src.join(first))
+ };
+
for path in &paths[1..] {
- walker.add(path);
+ if should_look_for_shortcut_dir(path) {
+ if let [single_candidate] = &find_shortcut_candidates(path)[..] {
+ walker.add(single_candidate);
+ } else {
+ walker.add(path);
+ }
+ } else {
+ walker.add(src.join(path));
+ }
}
+
walker
}
None => WalkBuilder::new(src.clone()),