2019-10-30 16:56:27 -07:00
|
|
|
//! Runs rustfmt on the repository.
|
|
|
|
|
2019-12-18 10:52:10 -05:00
|
|
|
use crate::Build;
|
2020-02-27 15:52:09 -05:00
|
|
|
use build_helper::{output, t};
|
2019-12-18 10:52:10 -05:00
|
|
|
use ignore::WalkBuilder;
|
|
|
|
use std::path::Path;
|
2019-12-22 16:43:54 -05:00
|
|
|
use std::process::Command;
|
2019-10-30 16:56:27 -07:00
|
|
|
|
2019-12-22 16:43:54 -05:00
|
|
|
fn rustfmt(src: &Path, rustfmt: &Path, path: &Path, check: bool) {
|
|
|
|
let mut cmd = Command::new(&rustfmt);
|
2019-12-18 10:52:10 -05:00
|
|
|
// avoid the submodule config paths from coming into play,
|
|
|
|
// we only allow a single global config for the workspace for now
|
2019-12-22 16:43:54 -05:00
|
|
|
cmd.arg("--config-path").arg(&src.canonicalize().unwrap());
|
|
|
|
cmd.arg("--edition").arg("2018");
|
2019-12-18 10:52:10 -05:00
|
|
|
cmd.arg("--unstable-features");
|
|
|
|
cmd.arg("--skip-children");
|
2019-10-30 16:56:27 -07:00
|
|
|
if check {
|
|
|
|
cmd.arg("--check");
|
|
|
|
}
|
2019-12-18 10:52:10 -05:00
|
|
|
cmd.arg(&path);
|
|
|
|
let cmd_debug = format!("{:?}", cmd);
|
|
|
|
let status = cmd.status().expect("executing rustfmt");
|
2020-01-14 04:44:57 +09:00
|
|
|
if !status.success() {
|
|
|
|
eprintln!(
|
|
|
|
"Running `{}` failed.\nIf you're running `tidy`, \
|
|
|
|
try again with `--bless` flag. Or, you just want to format \
|
|
|
|
code, run `./x.py fmt` instead.",
|
|
|
|
cmd_debug,
|
|
|
|
);
|
|
|
|
std::process::exit(1);
|
|
|
|
}
|
2019-12-18 10:52:10 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(serde::Deserialize)]
|
|
|
|
struct RustfmtConfig {
|
|
|
|
ignore: Vec<String>,
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn format(build: &Build, check: bool) {
|
2020-03-18 08:15:29 -07:00
|
|
|
if build.config.dry_run {
|
|
|
|
return;
|
|
|
|
}
|
2019-12-18 10:52:10 -05:00
|
|
|
let mut builder = ignore::types::TypesBuilder::new();
|
|
|
|
builder.add_defaults();
|
|
|
|
builder.select("rust");
|
|
|
|
let matcher = builder.build().unwrap();
|
2019-12-22 07:44:09 -05:00
|
|
|
let rustfmt_config = build.src.join("rustfmt.toml");
|
|
|
|
if !rustfmt_config.exists() {
|
|
|
|
eprintln!("Not running formatting checks; rustfmt.toml does not exist.");
|
|
|
|
eprintln!("This may happen in distributed tarballs.");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
let rustfmt_config = t!(std::fs::read_to_string(&rustfmt_config));
|
2019-12-18 10:52:10 -05:00
|
|
|
let rustfmt_config: RustfmtConfig = t!(toml::from_str(&rustfmt_config));
|
|
|
|
let mut ignore_fmt = ignore::overrides::OverrideBuilder::new(&build.src);
|
|
|
|
for ignore in rustfmt_config.ignore {
|
|
|
|
ignore_fmt.add(&format!("!{}", ignore)).expect(&ignore);
|
|
|
|
}
|
2020-02-27 15:52:09 -05:00
|
|
|
let untracked_paths_output = output(
|
|
|
|
Command::new("git").arg("status").arg("--porcelain").arg("--untracked-files=normal"),
|
|
|
|
);
|
|
|
|
let untracked_paths = untracked_paths_output
|
|
|
|
.lines()
|
|
|
|
.filter(|entry| entry.starts_with("??"))
|
|
|
|
.map(|entry| entry.split(" ").nth(1).expect("every git status entry should list a path"));
|
|
|
|
for untracked_path in untracked_paths {
|
|
|
|
eprintln!("skip untracked path {} during rustfmt invocations", untracked_path);
|
|
|
|
ignore_fmt.add(&format!("!{}", untracked_path)).expect(&untracked_path);
|
|
|
|
}
|
2019-12-18 10:52:10 -05:00
|
|
|
let ignore_fmt = ignore_fmt.build().unwrap();
|
2019-10-30 16:56:27 -07:00
|
|
|
|
2019-12-22 16:43:54 -05:00
|
|
|
let rustfmt_path = build.config.initial_rustfmt.as_ref().unwrap_or_else(|| {
|
|
|
|
eprintln!("./x.py fmt is not supported on this channel");
|
|
|
|
std::process::exit(1);
|
|
|
|
});
|
|
|
|
let src = build.src.clone();
|
|
|
|
let walker = WalkBuilder::new(&build.src).types(matcher).overrides(ignore_fmt).build_parallel();
|
|
|
|
walker.run(|| {
|
|
|
|
let src = src.clone();
|
|
|
|
let rustfmt_path = rustfmt_path.clone();
|
|
|
|
Box::new(move |entry| {
|
|
|
|
let entry = t!(entry);
|
|
|
|
if entry.file_type().map_or(false, |t| t.is_file()) {
|
|
|
|
rustfmt(&src, &rustfmt_path, &entry.path(), check);
|
|
|
|
}
|
|
|
|
ignore::WalkState::Continue
|
|
|
|
})
|
|
|
|
});
|
2019-10-30 16:56:27 -07:00
|
|
|
}
|