|
1 | 1 | //! Runs rustfmt on the repository.
|
2 | 2 |
|
3 |
| -use crate::{util, Build}; |
| 3 | +use crate::Build; |
4 | 4 | use std::process::Command;
|
| 5 | +use ignore::WalkBuilder; |
| 6 | +use std::path::Path; |
| 7 | +use build_helper::t; |
5 | 8 |
|
6 |
| -pub fn format(build: &Build, check: bool) { |
7 |
| - let target = &build.build; |
| 9 | +fn rustfmt(build: &Build, path: &Path, check: bool) { |
8 | 10 | let rustfmt_path = build.config.initial_rustfmt.as_ref().unwrap_or_else(|| {
|
9 | 11 | eprintln!("./x.py fmt is not supported on this channel");
|
10 | 12 | std::process::exit(1);
|
11 |
| - }).clone(); |
12 |
| - let cargo_fmt_path = rustfmt_path.with_file_name(util::exe("cargo-fmt", &target)); |
13 |
| - assert!(cargo_fmt_path.is_file(), "{} not a file", cargo_fmt_path.display()); |
14 |
| - |
15 |
| - let mut cmd = Command::new(&cargo_fmt_path); |
16 |
| - // cargo-fmt calls rustfmt as a bare command, so we need it to only find the correct one |
17 |
| - cmd.env("PATH", cargo_fmt_path.parent().unwrap()); |
18 |
| - cmd.current_dir(&build.src); |
19 |
| - cmd.arg("fmt"); |
| 13 | + }); |
20 | 14 |
|
| 15 | + let mut cmd = Command::new(&rustfmt_path); |
| 16 | + // avoid the submodule config paths from coming into play, |
| 17 | + // we only allow a single global config for the workspace for now |
| 18 | + cmd.arg("--config-path").arg(&build.src.canonicalize().unwrap()); |
| 19 | + cmd.arg("--unstable-features"); |
| 20 | + cmd.arg("--skip-children"); |
21 | 21 | if check {
|
22 |
| - cmd.arg("--"); |
23 | 22 | cmd.arg("--check");
|
24 | 23 | }
|
| 24 | + cmd.arg(&path); |
| 25 | + let cmd_debug = format!("{:?}", cmd); |
| 26 | + let status = cmd.status().expect("executing rustfmt"); |
| 27 | + assert!(status.success(), "running {} successful", cmd_debug); |
| 28 | +} |
| 29 | + |
| 30 | +#[derive(serde::Deserialize)] |
| 31 | +struct RustfmtConfig { |
| 32 | + ignore: Vec<String>, |
| 33 | +} |
| 34 | + |
| 35 | +pub fn format(build: &Build, check: bool) { |
| 36 | + let mut builder = ignore::types::TypesBuilder::new(); |
| 37 | + builder.add_defaults(); |
| 38 | + builder.select("rust"); |
| 39 | + let matcher = builder.build().unwrap(); |
| 40 | + |
| 41 | + let rustfmt_config = t!(std::fs::read_to_string(build.src.join("rustfmt.toml"))); |
| 42 | + let rustfmt_config: RustfmtConfig = t!(toml::from_str(&rustfmt_config)); |
| 43 | + let mut ignore_fmt = ignore::overrides::OverrideBuilder::new(&build.src); |
| 44 | + for ignore in rustfmt_config.ignore { |
| 45 | + ignore_fmt.add(&format!("!{}", ignore)).expect(&ignore); |
| 46 | + } |
| 47 | + let ignore_fmt = ignore_fmt.build().unwrap(); |
25 | 48 |
|
26 |
| - let status = cmd.status().expect("executing cargo-fmt"); |
27 |
| - assert!(status.success(), "cargo-fmt errored with status {:?}", status); |
| 49 | + let walker = WalkBuilder::new(&build.src) |
| 50 | + .types(matcher) |
| 51 | + .overrides(ignore_fmt) |
| 52 | + .build(); |
| 53 | + for entry in walker { |
| 54 | + let entry = t!(entry); |
| 55 | + if entry.file_type().map_or(false, |t| t.is_file()) { |
| 56 | + rustfmt(build, &entry.path(), check); |
| 57 | + } |
| 58 | + } |
28 | 59 | }
|
0 commit comments