Implement ./x.py fmt [--check].

This commit is contained in:
Adam Perry 2019-10-30 16:56:27 -07:00 committed by Mark Rousskov
parent 72a844dee7
commit a08c56295a
5 changed files with 70 additions and 5 deletions

View File

@ -314,6 +314,7 @@ pub enum Kind {
Check,
Clippy,
Fix,
Format,
Test,
Bench,
Dist,
@ -353,7 +354,7 @@ macro_rules! describe {
tool::Miri,
native::Lld
),
Kind::Check | Kind::Clippy | Kind::Fix => describe!(
Kind::Check | Kind::Clippy | Kind::Fix | Kind::Format => describe!(
check::Std,
check::Rustc,
check::Rustdoc
@ -514,7 +515,7 @@ pub fn new(build: &Build) -> Builder<'_> {
Subcommand::Bench { ref paths, .. } => (Kind::Bench, &paths[..]),
Subcommand::Dist { ref paths } => (Kind::Dist, &paths[..]),
Subcommand::Install { ref paths } => (Kind::Install, &paths[..]),
Subcommand::Clean { .. } => panic!(),
Subcommand::Format { .. } | Subcommand::Clean { .. } => panic!(),
};
let builder = Builder {

View File

@ -5,6 +5,7 @@
use std::collections::{HashMap, HashSet};
use std::env;
use std::ffi::OsString;
use std::fs;
use std::path::{Path, PathBuf};
use std::process;
@ -149,6 +150,7 @@ pub struct Config {
// These are either the stage0 downloaded binaries or the locally installed ones.
pub initial_cargo: PathBuf,
pub initial_rustc: PathBuf,
pub initial_rustfmt: Option<PathBuf>,
pub out: PathBuf,
}
@ -348,12 +350,16 @@ struct TomlTarget {
impl Config {
fn path_from_python(var_key: &str) -> PathBuf {
match env::var_os(var_key) {
// Do not trust paths from Python and normalize them slightly (#49785).
Some(var_val) => Path::new(&var_val).components().collect(),
Some(var_val) => Self::normalize_python_path(var_val),
_ => panic!("expected '{}' to be set", var_key),
}
}
/// Normalizes paths from Python slightly. We don't trust paths from Python (#49785).
fn normalize_python_path(path: OsString) -> PathBuf {
Path::new(&path).components().collect()
}
pub fn default_opts() -> Config {
let mut config = Config::default();
config.llvm_optimize = true;
@ -380,6 +386,7 @@ pub fn default_opts() -> Config {
config.initial_rustc = Config::path_from_python("RUSTC");
config.initial_cargo = Config::path_from_python("CARGO");
config.initial_rustfmt = env::var_os("RUSTFMT").map(Config::normalize_python_path);
config
}

View File

@ -53,6 +53,9 @@ pub enum Subcommand {
Fix {
paths: Vec<PathBuf>,
},
Format {
check: bool,
},
Doc {
paths: Vec<PathBuf>,
},
@ -102,6 +105,7 @@ pub fn parse(args: &[String]) -> Flags {
check Compile either the compiler or libraries, using cargo check
clippy Run clippy
fix Run cargo fix
fmt Run rustfmt
test Build and run some test suites
bench Build and run some benchmarks
doc Build documentation
@ -160,6 +164,7 @@ pub fn parse(args: &[String]) -> Flags {
|| (s == "check")
|| (s == "clippy")
|| (s == "fix")
|| (s == "fmt")
|| (s == "test")
|| (s == "bench")
|| (s == "doc")
@ -222,6 +227,9 @@ pub fn parse(args: &[String]) -> Flags {
"clean" => {
opts.optflag("", "all", "clean all build artifacts");
}
"fmt" => {
opts.optflag("", "check", "check formatting instead of applying.");
}
_ => {}
};
@ -323,6 +331,17 @@ pub fn parse(args: &[String]) -> Flags {
./x.py fix src/libcore src/libproc_macro",
);
}
"fmt" => {
subcommand_help.push_str(
"\n
Arguments:
This subcommand optionally accepts a `--check` flag which succeeds if formatting is correct and
fails if it is not. For example:
./x.py fmt
./x.py fmt --check",
);
}
"test" => {
subcommand_help.push_str(
"\n
@ -388,7 +407,7 @@ pub fn parse(args: &[String]) -> Flags {
let maybe_rules_help = Builder::get_help(&build, subcommand.as_str());
extra_help.push_str(maybe_rules_help.unwrap_or_default().as_str());
} else if subcommand.as_str() != "clean" {
} else if !(subcommand.as_str() == "clean" || subcommand.as_str() == "fmt") {
extra_help.push_str(
format!(
"Run `./x.py {} -h -v` to see a list of available paths.",
@ -439,6 +458,11 @@ pub fn parse(args: &[String]) -> Flags {
all: matches.opt_present("all"),
}
}
"fmt" => {
Subcommand::Format {
check: matches.opt_present("check"),
}
}
"dist" => Subcommand::Dist { paths },
"install" => Subcommand::Install { paths },
_ => {

28
src/bootstrap/format.rs Normal file
View File

@ -0,0 +1,28 @@
//! Runs rustfmt on the repository.
use crate::{util, Build};
use std::process::Command;
pub fn format(build: &Build, check: bool) {
let target = &build.build;
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");
if check {
cmd.arg("--");
cmd.arg("--check");
}
let status = cmd.status().expect("executing cargo-fmt");
assert!(status.success(), "cargo-fmt errored with status {:?}", status);
}

View File

@ -147,6 +147,7 @@
mod cache;
mod tool;
mod toolstate;
mod format;
#[cfg(windows)]
mod job;
@ -421,6 +422,10 @@ pub fn build(&mut self) {
job::setup(self);
}
if let Subcommand::Format { check } = self.config.cmd {
return format::format(self, check);
}
if let Subcommand::Clean { all } = self.config.cmd {
return clean::clean(self, all);
}