diff options
| author | Mark Rousskov <mark.simulacrum@gmail.com> | 2019-12-18 10:52:10 -0500 |
|---|---|---|
| committer | Mark Rousskov <mark.simulacrum@gmail.com> | 2019-12-21 20:23:55 -0500 |
| commit | dddd8724271a2a38ce552f5b1062a7ea070ec126 (patch) | |
| tree | 8cfcd9fccb826db1dc7bf5646c45ce7ee000bcae /src/bootstrap | |
| parent | 2b081abe944a7915013e15ae602ac8cfe9f52a77 (diff) | |
| download | rust-dddd8724271a2a38ce552f5b1062a7ea070ec126.tar.gz rust-dddd8724271a2a38ce552f5b1062a7ea070ec126.zip | |
Implement rustfmt running manually using ignore crate
This replaces cargo-fmt with rustfmt with --skip-children which should allow us to format code without running into rust-lang/rustfmt#3930. This also bumps up the version of rustfmt used to a more recent one.
Diffstat (limited to 'src/bootstrap')
| -rw-r--r-- | src/bootstrap/Cargo.toml | 1 | ||||
| -rw-r--r-- | src/bootstrap/format.rs | 61 |
2 files changed, 47 insertions, 15 deletions
diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml index 7be16cf3f17..3ab00a6e147 100644 --- a/src/bootstrap/Cargo.toml +++ b/src/bootstrap/Cargo.toml @@ -47,6 +47,7 @@ serde_json = "1.0.2" toml = "0.5" lazy_static = "1.3.0" time = "0.1" +ignore = "0.4.10" [dev-dependencies] pretty_assertions = "0.5" diff --git a/src/bootstrap/format.rs b/src/bootstrap/format.rs index 0c542594eff..e253e525526 100644 --- a/src/bootstrap/format.rs +++ b/src/bootstrap/format.rs @@ -1,28 +1,59 @@ //! Runs rustfmt on the repository. -use crate::{util, Build}; +use crate::Build; use std::process::Command; +use ignore::WalkBuilder; +use std::path::Path; +use build_helper::t; -pub fn format(build: &Build, check: bool) { - let target = &build.build; +fn rustfmt(build: &Build, path: &Path, check: bool) { 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); - }).clone(); - let cargo_fmt_path = rustfmt_path.with_file_name(util::exe("cargo-fmt", &target)); - assert!(cargo_fmt_path.is_file(), "{} not a file", cargo_fmt_path.display()); - - let mut cmd = Command::new(&cargo_fmt_path); - // cargo-fmt calls rustfmt as a bare command, so we need it to only find the correct one - cmd.env("PATH", cargo_fmt_path.parent().unwrap()); - cmd.current_dir(&build.src); - cmd.arg("fmt"); + }); + let mut cmd = Command::new(&rustfmt_path); + // avoid the submodule config paths from coming into play, + // we only allow a single global config for the workspace for now + cmd.arg("--config-path").arg(&build.src.canonicalize().unwrap()); + cmd.arg("--unstable-features"); + cmd.arg("--skip-children"); if check { - cmd.arg("--"); cmd.arg("--check"); } + cmd.arg(&path); + let cmd_debug = format!("{:?}", cmd); + let status = cmd.status().expect("executing rustfmt"); + assert!(status.success(), "running {} successful", cmd_debug); +} + +#[derive(serde::Deserialize)] +struct RustfmtConfig { + ignore: Vec<String>, +} + +pub fn format(build: &Build, check: bool) { + let mut builder = ignore::types::TypesBuilder::new(); + builder.add_defaults(); + builder.select("rust"); + let matcher = builder.build().unwrap(); + + let rustfmt_config = t!(std::fs::read_to_string(build.src.join("rustfmt.toml"))); + 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); + } + let ignore_fmt = ignore_fmt.build().unwrap(); - let status = cmd.status().expect("executing cargo-fmt"); - assert!(status.success(), "cargo-fmt errored with status {:?}", status); + let walker = WalkBuilder::new(&build.src) + .types(matcher) + .overrides(ignore_fmt) + .build(); + for entry in walker { + let entry = t!(entry); + if entry.file_type().map_or(false, |t| t.is_file()) { + rustfmt(build, &entry.path(), check); + } + } } |
