Skip to content

Commit a08c562

Browse files
anpMark-Simulacrum
authored andcommitted
Implement ./x.py fmt [--check].
1 parent 72a844d commit a08c562

File tree

5 files changed

+70
-5
lines changed

5 files changed

+70
-5
lines changed

src/bootstrap/builder.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,7 @@ pub enum Kind {
314314
Check,
315315
Clippy,
316316
Fix,
317+
Format,
317318
Test,
318319
Bench,
319320
Dist,
@@ -353,7 +354,7 @@ impl<'a> Builder<'a> {
353354
tool::Miri,
354355
native::Lld
355356
),
356-
Kind::Check | Kind::Clippy | Kind::Fix => describe!(
357+
Kind::Check | Kind::Clippy | Kind::Fix | Kind::Format => describe!(
357358
check::Std,
358359
check::Rustc,
359360
check::Rustdoc
@@ -514,7 +515,7 @@ impl<'a> Builder<'a> {
514515
Subcommand::Bench { ref paths, .. } => (Kind::Bench, &paths[..]),
515516
Subcommand::Dist { ref paths } => (Kind::Dist, &paths[..]),
516517
Subcommand::Install { ref paths } => (Kind::Install, &paths[..]),
517-
Subcommand::Clean { .. } => panic!(),
518+
Subcommand::Format { .. } | Subcommand::Clean { .. } => panic!(),
518519
};
519520

520521
let builder = Builder {

src/bootstrap/config.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
66
use std::collections::{HashMap, HashSet};
77
use std::env;
8+
use std::ffi::OsString;
89
use std::fs;
910
use std::path::{Path, PathBuf};
1011
use std::process;
@@ -149,6 +150,7 @@ pub struct Config {
149150
// These are either the stage0 downloaded binaries or the locally installed ones.
150151
pub initial_cargo: PathBuf,
151152
pub initial_rustc: PathBuf,
153+
pub initial_rustfmt: Option<PathBuf>,
152154
pub out: PathBuf,
153155
}
154156

@@ -348,12 +350,16 @@ struct TomlTarget {
348350
impl Config {
349351
fn path_from_python(var_key: &str) -> PathBuf {
350352
match env::var_os(var_key) {
351-
// Do not trust paths from Python and normalize them slightly (#49785).
352-
Some(var_val) => Path::new(&var_val).components().collect(),
353+
Some(var_val) => Self::normalize_python_path(var_val),
353354
_ => panic!("expected '{}' to be set", var_key),
354355
}
355356
}
356357

358+
/// Normalizes paths from Python slightly. We don't trust paths from Python (#49785).
359+
fn normalize_python_path(path: OsString) -> PathBuf {
360+
Path::new(&path).components().collect()
361+
}
362+
357363
pub fn default_opts() -> Config {
358364
let mut config = Config::default();
359365
config.llvm_optimize = true;
@@ -380,6 +386,7 @@ impl Config {
380386

381387
config.initial_rustc = Config::path_from_python("RUSTC");
382388
config.initial_cargo = Config::path_from_python("CARGO");
389+
config.initial_rustfmt = env::var_os("RUSTFMT").map(Config::normalize_python_path);
383390

384391
config
385392
}

src/bootstrap/flags.rs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ pub enum Subcommand {
5353
Fix {
5454
paths: Vec<PathBuf>,
5555
},
56+
Format {
57+
check: bool,
58+
},
5659
Doc {
5760
paths: Vec<PathBuf>,
5861
},
@@ -102,6 +105,7 @@ Subcommands:
102105
check Compile either the compiler or libraries, using cargo check
103106
clippy Run clippy
104107
fix Run cargo fix
108+
fmt Run rustfmt
105109
test Build and run some test suites
106110
bench Build and run some benchmarks
107111
doc Build documentation
@@ -160,6 +164,7 @@ To learn more about a subcommand, run `./x.py <subcommand> -h`"
160164
|| (s == "check")
161165
|| (s == "clippy")
162166
|| (s == "fix")
167+
|| (s == "fmt")
163168
|| (s == "test")
164169
|| (s == "bench")
165170
|| (s == "doc")
@@ -222,6 +227,9 @@ To learn more about a subcommand, run `./x.py <subcommand> -h`"
222227
"clean" => {
223228
opts.optflag("", "all", "clean all build artifacts");
224229
}
230+
"fmt" => {
231+
opts.optflag("", "check", "check formatting instead of applying.");
232+
}
225233
_ => {}
226234
};
227235

@@ -323,6 +331,17 @@ Arguments:
323331
./x.py fix src/libcore src/libproc_macro",
324332
);
325333
}
334+
"fmt" => {
335+
subcommand_help.push_str(
336+
"\n
337+
Arguments:
338+
This subcommand optionally accepts a `--check` flag which succeeds if formatting is correct and
339+
fails if it is not. For example:
340+
341+
./x.py fmt
342+
./x.py fmt --check",
343+
);
344+
}
326345
"test" => {
327346
subcommand_help.push_str(
328347
"\n
@@ -388,7 +407,7 @@ Arguments:
388407

389408
let maybe_rules_help = Builder::get_help(&build, subcommand.as_str());
390409
extra_help.push_str(maybe_rules_help.unwrap_or_default().as_str());
391-
} else if subcommand.as_str() != "clean" {
410+
} else if !(subcommand.as_str() == "clean" || subcommand.as_str() == "fmt") {
392411
extra_help.push_str(
393412
format!(
394413
"Run `./x.py {} -h -v` to see a list of available paths.",
@@ -439,6 +458,11 @@ Arguments:
439458
all: matches.opt_present("all"),
440459
}
441460
}
461+
"fmt" => {
462+
Subcommand::Format {
463+
check: matches.opt_present("check"),
464+
}
465+
}
442466
"dist" => Subcommand::Dist { paths },
443467
"install" => Subcommand::Install { paths },
444468
_ => {

src/bootstrap/format.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
//! Runs rustfmt on the repository.
2+
3+
use crate::{util, Build};
4+
use std::process::Command;
5+
6+
pub fn format(build: &Build, check: bool) {
7+
let target = &build.build;
8+
let rustfmt_path = build.config.initial_rustfmt.as_ref().unwrap_or_else(|| {
9+
eprintln!("./x.py fmt is not supported on this channel");
10+
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");
20+
21+
if check {
22+
cmd.arg("--");
23+
cmd.arg("--check");
24+
}
25+
26+
let status = cmd.status().expect("executing cargo-fmt");
27+
assert!(status.success(), "cargo-fmt errored with status {:?}", status);
28+
}

src/bootstrap/lib.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ mod builder;
147147
mod cache;
148148
mod tool;
149149
mod toolstate;
150+
mod format;
150151

151152
#[cfg(windows)]
152153
mod job;
@@ -421,6 +422,10 @@ impl Build {
421422
job::setup(self);
422423
}
423424

425+
if let Subcommand::Format { check } = self.config.cmd {
426+
return format::format(self, check);
427+
}
428+
424429
if let Subcommand::Clean { all } = self.config.cmd {
425430
return clean::clean(self, all);
426431
}

0 commit comments

Comments
 (0)