Skip to content

Commit

Permalink
Implement ./x.py fmt [--check].
Browse files Browse the repository at this point in the history
  • Loading branch information
anp authored and Mark-Simulacrum committed Dec 22, 2019
1 parent 72a844d commit a08c562
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 5 deletions.
5 changes: 3 additions & 2 deletions src/bootstrap/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,7 @@ pub enum Kind {
Check,
Clippy,
Fix,
Format,
Test,
Bench,
Dist,
Expand Down Expand Up @@ -353,7 +354,7 @@ impl<'a> Builder<'a> {
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
Expand Down Expand Up @@ -514,7 +515,7 @@ impl<'a> Builder<'a> {
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 {
Expand Down
11 changes: 9 additions & 2 deletions src/bootstrap/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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,
}

Expand Down Expand Up @@ -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;
Expand All @@ -380,6 +386,7 @@ impl 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
}
Expand Down
26 changes: 25 additions & 1 deletion src/bootstrap/flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ pub enum Subcommand {
Fix {
paths: Vec<PathBuf>,
},
Format {
check: bool,
},
Doc {
paths: Vec<PathBuf>,
},
Expand Down Expand Up @@ -102,6 +105,7 @@ Subcommands:
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
Expand Down Expand Up @@ -160,6 +164,7 @@ To learn more about a subcommand, run `./x.py <subcommand> -h`"
|| (s == "check")
|| (s == "clippy")
|| (s == "fix")
|| (s == "fmt")
|| (s == "test")
|| (s == "bench")
|| (s == "doc")
Expand Down Expand Up @@ -222,6 +227,9 @@ To learn more about a subcommand, run `./x.py <subcommand> -h`"
"clean" => {
opts.optflag("", "all", "clean all build artifacts");
}
"fmt" => {
opts.optflag("", "check", "check formatting instead of applying.");
}
_ => {}
};

Expand Down Expand Up @@ -323,6 +331,17 @@ Arguments:
./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
Expand Down Expand Up @@ -388,7 +407,7 @@ Arguments:

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.",
Expand Down Expand Up @@ -439,6 +458,11 @@ Arguments:
all: matches.opt_present("all"),
}
}
"fmt" => {
Subcommand::Format {
check: matches.opt_present("check"),
}
}
"dist" => Subcommand::Dist { paths },
"install" => Subcommand::Install { paths },
_ => {
Expand Down
28 changes: 28 additions & 0 deletions src/bootstrap/format.rs
Original file line number Diff line number Diff line change
@@ -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);
}
5 changes: 5 additions & 0 deletions src/bootstrap/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ mod builder;
mod cache;
mod tool;
mod toolstate;
mod format;

#[cfg(windows)]
mod job;
Expand Down Expand Up @@ -421,6 +422,10 @@ impl Build {
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);
}
Expand Down

0 comments on commit a08c562

Please sign in to comment.