]> git.lizzy.rs Git - rust.git/blob - src/bootstrap/format.rs
rustc: Allow cdylibs to link against dylibs
[rust.git] / src / bootstrap / format.rs
1 //! Runs rustfmt on the repository.
2
3 use crate::Build;
4 use build_helper::t;
5 use ignore::WalkBuilder;
6 use std::path::Path;
7 use std::process::Command;
8
9 fn rustfmt(src: &Path, rustfmt: &Path, path: &Path, check: bool) {
10     let mut cmd = Command::new(&rustfmt);
11     // avoid the submodule config paths from coming into play,
12     // we only allow a single global config for the workspace for now
13     cmd.arg("--config-path").arg(&src.canonicalize().unwrap());
14     cmd.arg("--edition").arg("2018");
15     cmd.arg("--unstable-features");
16     cmd.arg("--skip-children");
17     if check {
18         cmd.arg("--check");
19     }
20     cmd.arg(&path);
21     let cmd_debug = format!("{:?}", cmd);
22     let status = cmd.status().expect("executing rustfmt");
23     if !status.success() {
24         eprintln!(
25             "Running `{}` failed.\nIf you're running `tidy`, \
26             try again with `--bless` flag. Or, you just want to format \
27             code, run `./x.py fmt` instead.",
28             cmd_debug,
29         );
30         std::process::exit(1);
31     }
32 }
33
34 #[derive(serde::Deserialize)]
35 struct RustfmtConfig {
36     ignore: Vec<String>,
37 }
38
39 pub fn format(build: &Build, check: bool) {
40     let mut builder = ignore::types::TypesBuilder::new();
41     builder.add_defaults();
42     builder.select("rust");
43     let matcher = builder.build().unwrap();
44     let rustfmt_config = build.src.join("rustfmt.toml");
45     if !rustfmt_config.exists() {
46         eprintln!("Not running formatting checks; rustfmt.toml does not exist.");
47         eprintln!("This may happen in distributed tarballs.");
48         return;
49     }
50     let rustfmt_config = t!(std::fs::read_to_string(&rustfmt_config));
51     let rustfmt_config: RustfmtConfig = t!(toml::from_str(&rustfmt_config));
52     let mut ignore_fmt = ignore::overrides::OverrideBuilder::new(&build.src);
53     for ignore in rustfmt_config.ignore {
54         ignore_fmt.add(&format!("!{}", ignore)).expect(&ignore);
55     }
56     let ignore_fmt = ignore_fmt.build().unwrap();
57
58     let rustfmt_path = build.config.initial_rustfmt.as_ref().unwrap_or_else(|| {
59         eprintln!("./x.py fmt is not supported on this channel");
60         std::process::exit(1);
61     });
62     let src = build.src.clone();
63     let walker = WalkBuilder::new(&build.src).types(matcher).overrides(ignore_fmt).build_parallel();
64     walker.run(|| {
65         let src = src.clone();
66         let rustfmt_path = rustfmt_path.clone();
67         Box::new(move |entry| {
68             let entry = t!(entry);
69             if entry.file_type().map_or(false, |t| t.is_file()) {
70                 rustfmt(&src, &rustfmt_path, &entry.path(), check);
71             }
72             ignore::WalkState::Continue
73         })
74     });
75 }