Skip to content

Commit 32643dc

Browse files
committed
Fix .\miri fmt on Windows
1 parent c414c08 commit 32643dc

File tree

2 files changed

+63
-30
lines changed

2 files changed

+63
-30
lines changed

src/tools/miri/miri-script/src/commands.rs

Lines changed: 18 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -526,37 +526,27 @@ impl Command {
526526
}
527527

528528
fn fmt(flags: Vec<OsString>) -> Result<()> {
529+
use itertools::Itertools;
530+
529531
let e = MiriEnv::new()?;
530-
let toolchain = &e.toolchain;
531532
let config_path = path!(e.miri_dir / "rustfmt.toml");
532533

533-
let mut cmd = cmd!(
534-
e.sh,
535-
"rustfmt +{toolchain} --edition=2021 --config-path {config_path} --unstable-features --skip-children {flags...}"
536-
);
537-
eprintln!("$ {cmd} ...");
538-
539-
// Add all the filenames to the command.
540-
// FIXME: `rustfmt` will follow the `mod` statements in these files, so we get a bunch of
541-
// duplicate diffs.
542-
for item in WalkDir::new(&e.miri_dir).into_iter().filter_entry(|entry| {
543-
let name = entry.file_name().to_string_lossy();
544-
let ty = entry.file_type();
545-
if ty.is_file() {
546-
name.ends_with(".rs")
547-
} else {
548-
// dir or symlink. skip `target` and `.git`.
549-
&name != "target" && &name != ".git"
550-
}
551-
}) {
552-
let item = item?;
553-
if item.file_type().is_file() {
554-
cmd = cmd.arg(item.into_path());
555-
}
556-
}
534+
// Collect each rust file in the miri repo.
535+
let files = WalkDir::new(&e.miri_dir)
536+
.into_iter()
537+
.filter_entry(|entry| {
538+
let name = entry.file_name().to_string_lossy();
539+
let ty = entry.file_type();
540+
if ty.is_file() {
541+
name.ends_with(".rs")
542+
} else {
543+
// dir or symlink. skip `target` and `.git`.
544+
&name != "target" && &name != ".git"
545+
}
546+
})
547+
.filter_ok(|item| item.file_type().is_file())
548+
.map_ok(|item| item.into_path());
557549

558-
// We want our own error message, repeating the command is too much.
559-
cmd.quiet().run().map_err(|_| anyhow!("`rustfmt` failed"))?;
560-
Ok(())
550+
e.format_files(files, &e.toolchain[..], &config_path, &flags[..])
561551
}
562552
}

src/tools/miri/miri-script/src/util.rs

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::ffi::{OsStr, OsString};
2-
use std::path::PathBuf;
2+
use std::path::{Path, PathBuf};
33

4-
use anyhow::{Context, Result};
4+
use anyhow::{anyhow, Context, Result};
55
use dunce::canonicalize;
66
use path_macro::path;
77
use xshell::{cmd, Shell};
@@ -145,4 +145,47 @@ impl MiriEnv {
145145
.run()?;
146146
Ok(())
147147
}
148+
149+
/// Receives an iterator of files.
150+
/// Will format each file with the miri rustfmt config.
151+
/// Does not follow module relationships.
152+
pub fn format_files(
153+
&self,
154+
files: impl Iterator<Item = Result<PathBuf, walkdir::Error>>,
155+
toolchain: &str,
156+
config_path: &Path,
157+
flags: &[OsString],
158+
) -> anyhow::Result<()> {
159+
use itertools::Itertools;
160+
161+
let mut first = true;
162+
163+
// Format in batches as not all out files fit into Windows' command argument limit.
164+
for batch in &files.chunks(256) {
165+
// Build base command.
166+
let mut cmd = cmd!(
167+
self.sh,
168+
"rustfmt +{toolchain} --edition=2021 --config-path {config_path} --unstable-features --skip-children {flags...}"
169+
);
170+
if first {
171+
eprintln!("$ {cmd} ...");
172+
first = false;
173+
}
174+
// Add files.
175+
for file in batch {
176+
// Make it a relative path so that on platforms with extremely tight argument
177+
// limits (like Windows), we become immune to someone cloning the repo
178+
// 50 directories deep.
179+
let file = file?;
180+
let file = file.strip_prefix(&self.miri_dir)?;
181+
cmd = cmd.arg(file);
182+
}
183+
184+
// Run commands.
185+
// We want our own error message, repeating the command is too much.
186+
cmd.quiet().run().map_err(|_| anyhow!("`rustfmt` failed"))?;
187+
}
188+
189+
Ok(())
190+
}
148191
}

0 commit comments

Comments
 (0)