about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2023-02-13 23:25:12 +0100
committerGitHub <noreply@github.com>2023-02-13 23:25:12 +0100
commit7efb884b9c1e112503a77ccb013bdb8feb1adc81 (patch)
treeed6a0a851ac772de321c1b471328ab6fb2df97dc /src
parent5f3d360844fae27ab3318fd715e81ebcc444c876 (diff)
parentb10d744b87fcaaeea1a2ec2a299dba494c1f3d82 (diff)
downloadrust-7efb884b9c1e112503a77ccb013bdb8feb1adc81.tar.gz
rust-7efb884b9c1e112503a77ccb013bdb8feb1adc81.zip
Rollup merge of #107948 - jieyouxu:issue-107944, r=ozkanonur
Allow shortcuts to directories to be used for ./x.py fmt

Fixes #107944.

Maximum recursive search depth is 3 and only accepts shortcuts for directories. If there are no shortcut candidates, the previous behavior to panic is preserved. If there are multiple candidates, the shortcut candidates are ignored.

After this change, `./x.py fmt std` no longer panics and formats `library/std` instead.
Diffstat (limited to 'src')
-rw-r--r--src/bootstrap/format.rs40
1 files changed, 38 insertions, 2 deletions
diff --git a/src/bootstrap/format.rs b/src/bootstrap/format.rs
index 6c9c26faef6..615794958d0 100644
--- a/src/bootstrap/format.rs
+++ b/src/bootstrap/format.rs
@@ -193,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(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(path);
+                }
             }
+
             walker
         }
         None => WalkBuilder::new(src.clone()),