about summary refs log tree commit diff
diff options
context:
space:
mode:
authorljedrz <ljedrz@gmail.com>2018-12-04 19:26:54 +0100
committerljedrz <ljedrz@gmail.com>2019-05-25 15:30:16 +0200
commit2f3533b7582c735969e9e2aa32d5845d3b565350 (patch)
treed0c6936de89faf43a1b70bdc44588cc43e1cfb67
parent315ab95a9c13cbb69ae8538fcd69b9f7b0c30f89 (diff)
downloadrust-2f3533b7582c735969e9e2aa32d5845d3b565350.tar.gz
rust-2f3533b7582c735969e9e2aa32d5845d3b565350.zip
Add clippy and fix commands to x.py
-rw-r--r--src/bootstrap/builder.rs25
-rw-r--r--src/bootstrap/check.rs37
-rw-r--r--src/bootstrap/compile.rs24
-rw-r--r--src/bootstrap/flags.rs34
-rw-r--r--src/bootstrap/tool.rs2
5 files changed, 105 insertions, 17 deletions
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index e616b2647a9..198b7dbc3f9 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -318,6 +318,8 @@ impl<'a> ShouldRun<'a> {
 pub enum Kind {
     Build,
     Check,
+    Clippy,
+    Fix,
     Test,
     Bench,
     Dist,
@@ -359,7 +361,7 @@ impl<'a> Builder<'a> {
                 tool::Miri,
                 native::Lld
             ),
-            Kind::Check => describe!(
+            Kind::Check | Kind::Clippy | Kind::Fix => describe!(
                 check::Std,
                 check::Test,
                 check::Rustc,
@@ -520,6 +522,8 @@ impl<'a> Builder<'a> {
         let (kind, paths) = match build.config.cmd {
             Subcommand::Build { ref paths } => (Kind::Build, &paths[..]),
             Subcommand::Check { ref paths } => (Kind::Check, &paths[..]),
+            Subcommand::Clippy { ref paths } => (Kind::Clippy, &paths[..]),
+            Subcommand::Fix { ref paths } => (Kind::Fix, &paths[..]),
             Subcommand::Doc { ref paths } => (Kind::Doc, &paths[..]),
             Subcommand::Test { ref paths, .. } => (Kind::Test, &paths[..]),
             Subcommand::Bench { ref paths, .. } => (Kind::Bench, &paths[..]),
@@ -757,17 +761,17 @@ impl<'a> Builder<'a> {
         };
 
         let libstd_stamp = match cmd {
-            "check" => check::libstd_stamp(self, cmp, target),
+            "check" | "clippy" | "fix" => check::libstd_stamp(self, cmp, target),
             _ => compile::libstd_stamp(self, cmp, target),
         };
 
         let libtest_stamp = match cmd {
-            "check" => check::libtest_stamp(self, cmp, target),
+            "check" | "clippy" | "fix" => check::libtest_stamp(self, cmp, target),
             _ => compile::libstd_stamp(self, cmp, target),
         };
 
         let librustc_stamp = match cmd {
-            "check" => check::librustc_stamp(self, cmp, target),
+            "check" | "clippy" | "fix" => check::librustc_stamp(self, cmp, target),
             _ => compile::librustc_stamp(self, cmp, target),
         };
 
@@ -831,9 +835,9 @@ impl<'a> Builder<'a> {
             assert_eq!(target, compiler.host);
         }
 
-        // Set a flag for `check` so that certain build scripts can do less work
-        // (e.g., not building/requiring LLVM).
-        if cmd == "check" {
+        // Set a flag for `check`/`clippy`/`fix`, so that certain build
+        // scripts can do less work (e.g. not building/requiring LLVM).
+        if cmd == "check" || cmd == "clippy" || cmd == "fix" {
             cargo.env("RUST_CHECK", "1");
         }
 
@@ -898,6 +902,11 @@ impl<'a> Builder<'a> {
             extra_args.push_str(&s);
         }
 
+        if cmd == "clippy" {
+            extra_args.push_str("-Zforce-unstable-if-unmarked -Zunstable-options \
+                --json-rendered=termcolor");
+        }
+
         if !extra_args.is_empty() {
             cargo.env(
                 "RUSTFLAGS",
@@ -966,7 +975,7 @@ impl<'a> Builder<'a> {
         if let Some(ref error_format) = self.config.rustc_error_format {
             cargo.env("RUSTC_ERROR_FORMAT", error_format);
         }
-        if cmd != "build" && cmd != "check" && cmd != "rustc" && want_rustdoc {
+        if !(["build", "check", "clippy", "fix", "rustc"].contains(&cmd)) && want_rustdoc {
             cargo.env("RUSTDOC_LIBDIR", self.rustc_libdir(compiler));
         }
 
diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs
index a30b465698e..bdf5306d4b5 100644
--- a/src/bootstrap/check.rs
+++ b/src/bootstrap/check.rs
@@ -1,8 +1,8 @@
-//! Implementation of compiling the compiler and standard library, in "check" mode.
+//! Implementation of compiling the compiler and standard library, in "check"-based modes.
 
 use crate::compile::{run_cargo, std_cargo, test_cargo, rustc_cargo, rustc_cargo_env,
                      add_to_sysroot};
-use crate::builder::{RunConfig, Builder, ShouldRun, Step};
+use crate::builder::{RunConfig, Builder, Kind, ShouldRun, Step};
 use crate::tool::{prepare_tool_cargo, SourceType};
 use crate::{Compiler, Mode};
 use crate::cache::{INTERNER, Interned};
@@ -13,6 +13,22 @@ pub struct Std {
     pub target: Interned<String>,
 }
 
+fn args(kind: Kind) -> Vec<String> {
+    match kind {
+        Kind::Clippy => vec!["--".to_owned(), "--cap-lints".to_owned(), "warn".to_owned()],
+        _ => Vec::new()
+    }
+}
+
+fn cargo_subcommand(kind: Kind) -> &'static str {
+    match kind {
+        Kind::Check => "check",
+        Kind::Clippy => "clippy",
+        Kind::Fix => "fix",
+        _ => unreachable!()
+    }
+}
+
 impl Step for Std {
     type Output = ();
     const DEFAULT: bool = true;
@@ -31,13 +47,14 @@ impl Step for Std {
         let target = self.target;
         let compiler = builder.compiler(0, builder.config.build);
 
-        let mut cargo = builder.cargo(compiler, Mode::Std, target, "check");
+        let mut cargo = builder.cargo(compiler, Mode::Std, target, cargo_subcommand(builder.kind));
         std_cargo(builder, &compiler, target, &mut cargo);
 
         let _folder = builder.fold_output(|| format!("stage{}-std", compiler.stage));
         builder.info(&format!("Checking std artifacts ({} -> {})", &compiler.host, target));
         run_cargo(builder,
                   &mut cargo,
+                  args(builder.kind),
                   &libstd_stamp(builder, compiler, target),
                   true);
 
@@ -78,13 +95,15 @@ impl Step for Rustc {
 
         builder.ensure(Test { target });
 
-        let mut cargo = builder.cargo(compiler, Mode::Rustc, target, "check");
+        let mut cargo = builder.cargo(compiler, Mode::Rustc, target,
+            cargo_subcommand(builder.kind));
         rustc_cargo(builder, &mut cargo);
 
         let _folder = builder.fold_output(|| format!("stage{}-rustc", compiler.stage));
         builder.info(&format!("Checking compiler artifacts ({} -> {})", &compiler.host, target));
         run_cargo(builder,
                   &mut cargo,
+                  args(builder.kind),
                   &librustc_stamp(builder, compiler, target),
                   true);
 
@@ -127,7 +146,8 @@ impl Step for CodegenBackend {
 
         builder.ensure(Rustc { target });
 
-        let mut cargo = builder.cargo(compiler, Mode::Codegen, target, "check");
+        let mut cargo = builder.cargo(compiler, Mode::Codegen, target,
+            cargo_subcommand(builder.kind));
         cargo.arg("--manifest-path").arg(builder.src.join("src/librustc_codegen_llvm/Cargo.toml"));
         rustc_cargo_env(builder, &mut cargo);
 
@@ -136,6 +156,7 @@ impl Step for CodegenBackend {
         let _folder = builder.fold_output(|| format!("stage{}-rustc_codegen_llvm", compiler.stage));
         run_cargo(builder,
                   &mut cargo,
+                  args(builder.kind),
                   &codegen_backend_stamp(builder, compiler, target, backend),
                   true);
     }
@@ -166,13 +187,14 @@ impl Step for Test {
 
         builder.ensure(Std { target });
 
-        let mut cargo = builder.cargo(compiler, Mode::Test, target, "check");
+        let mut cargo = builder.cargo(compiler, Mode::Test, target, cargo_subcommand(builder.kind));
         test_cargo(builder, &compiler, target, &mut cargo);
 
         let _folder = builder.fold_output(|| format!("stage{}-test", compiler.stage));
         builder.info(&format!("Checking test artifacts ({} -> {})", &compiler.host, target));
         run_cargo(builder,
                   &mut cargo,
+                  args(builder.kind),
                   &libtest_stamp(builder, compiler, target),
                   true);
 
@@ -212,7 +234,7 @@ impl Step for Rustdoc {
                                            compiler,
                                            Mode::ToolRustc,
                                            target,
-                                           "check",
+                                           cargo_subcommand(builder.kind),
                                            "src/tools/rustdoc",
                                            SourceType::InTree,
                                            &[]);
@@ -221,6 +243,7 @@ impl Step for Rustdoc {
         println!("Checking rustdoc artifacts ({} -> {})", &compiler.host, target);
         run_cargo(builder,
                   &mut cargo,
+                  args(builder.kind),
                   &rustdoc_stamp(builder, compiler, target),
                   true);
 
diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
index 6c81b6ada2b..50c9602de1b 100644
--- a/src/bootstrap/compile.rs
+++ b/src/bootstrap/compile.rs
@@ -100,6 +100,7 @@ impl Step for Std {
                 &compiler.host, target));
         run_cargo(builder,
                   &mut cargo,
+                  vec![],
                   &libstd_stamp(builder, compiler, target),
                   false);
 
@@ -425,6 +426,7 @@ impl Step for Test {
                 &compiler.host, target));
         run_cargo(builder,
                   &mut cargo,
+                  vec![],
                   &libtest_stamp(builder, compiler, target),
                   false);
 
@@ -556,6 +558,7 @@ impl Step for Rustc {
                  compiler.stage, &compiler.host, target));
         run_cargo(builder,
                   &mut cargo,
+                  vec![],
                   &librustc_stamp(builder, compiler, target),
                   false);
 
@@ -707,6 +710,7 @@ impl Step for CodegenBackend {
         let _folder = builder.fold_output(|| format!("stage{}-rustc_codegen_llvm", compiler.stage));
         let files = run_cargo(builder,
                               cargo.arg("--features").arg(features),
+                              vec![],
                               &tmp_stamp,
                               false);
         if builder.config.dry_run {
@@ -1077,6 +1081,7 @@ pub fn add_to_sysroot(
 
 pub fn run_cargo(builder: &Builder<'_>,
                  cargo: &mut Command,
+                 tail_args: Vec<String>,
                  stamp: &Path,
                  is_check: bool)
     -> Vec<PathBuf>
@@ -1099,7 +1104,7 @@ pub fn run_cargo(builder: &Builder<'_>,
     // files we need to probe for later.
     let mut deps = Vec::new();
     let mut toplevel = Vec::new();
-    let ok = stream_cargo(builder, cargo, &mut |msg| {
+    let ok = stream_cargo(builder, cargo, tail_args, &mut |msg| {
         let (filenames, crate_types) = match msg {
             CargoMessage::CompilerArtifact {
                 filenames,
@@ -1108,6 +1113,10 @@ pub fn run_cargo(builder: &Builder<'_>,
                 },
                 ..
             } => (filenames, crate_types),
+            CargoMessage::CompilerMessage { message } => {
+                eprintln!("{}", message.rendered);
+                return;
+            }
             _ => return,
         };
         for filename in filenames {
@@ -1235,6 +1244,7 @@ pub fn run_cargo(builder: &Builder<'_>,
 pub fn stream_cargo(
     builder: &Builder<'_>,
     cargo: &mut Command,
+    tail_args: Vec<String>,
     cb: &mut dyn FnMut(CargoMessage<'_>),
 ) -> bool {
     if builder.config.dry_run {
@@ -1245,6 +1255,10 @@ pub fn stream_cargo(
     cargo.arg("--message-format").arg("json")
          .stdout(Stdio::piped());
 
+    for arg in tail_args {
+        cargo.arg(arg);
+    }
+
     builder.verbose(&format!("running: {:?}", cargo));
     let mut child = match cargo.spawn() {
         Ok(child) => child,
@@ -1291,5 +1305,13 @@ pub enum CargoMessage<'a> {
     },
     BuildScriptExecuted {
         package_id: Cow<'a, str>,
+    },
+    CompilerMessage {
+        message: ClippyMessage<'a>
     }
 }
+
+#[derive(Deserialize)]
+pub struct ClippyMessage<'a> {
+    rendered: Cow<'a, str>,
+}
diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs
index a1f89d6c86f..4774c0a51c0 100644
--- a/src/bootstrap/flags.rs
+++ b/src/bootstrap/flags.rs
@@ -44,6 +44,12 @@ pub enum Subcommand {
     Check {
         paths: Vec<PathBuf>,
     },
+    Clippy {
+        paths: Vec<PathBuf>,
+    },
+    Fix {
+        paths: Vec<PathBuf>,
+    },
     Doc {
         paths: Vec<PathBuf>,
     },
@@ -90,6 +96,8 @@ Usage: x.py <subcommand> [options] [<paths>...]
 Subcommands:
     build       Compile either the compiler or libraries
     check       Compile either the compiler or libraries, using cargo check
+    clippy      Run clippy
+    fix         Run cargo fix
     test        Build and run some test suites
     bench       Build and run some benchmarks
     doc         Build documentation
@@ -146,6 +154,8 @@ To learn more about a subcommand, run `./x.py <subcommand> -h`"
         let subcommand = args.iter().find(|&s| {
             (s == "build")
                 || (s == "check")
+                || (s == "clippy")
+                || (s == "fix")
                 || (s == "test")
                 || (s == "bench")
                 || (s == "doc")
@@ -281,6 +291,28 @@ Arguments:
     the compiler.",
                 );
             }
+            "clippy" => {
+                subcommand_help.push_str(
+                    "\n
+Arguments:
+    This subcommand accepts a number of paths to directories to the crates
+    and/or artifacts to run clippy against. For example:
+
+        ./x.py clippy src/libcore
+        ./x.py clippy src/libcore src/libproc_macro",
+                );
+            }
+            "fix" => {
+                subcommand_help.push_str(
+                    "\n
+Arguments:
+    This subcommand accepts a number of paths to directories to the crates
+    and/or artifacts to run `cargo fix` against. For example:
+
+        ./x.py fix src/libcore
+        ./x.py fix src/libcore src/libproc_macro",
+                );
+            }
             "test" => {
                 subcommand_help.push_str(
                     "\n
@@ -363,6 +395,8 @@ Arguments:
         let cmd = match subcommand.as_str() {
             "build" => Subcommand::Build { paths },
             "check" => Subcommand::Check { paths },
+            "clippy" => Subcommand::Clippy { paths },
+            "fix" => Subcommand::Fix { paths },
             "test" => Subcommand::Test {
                 paths,
                 bless: matches.opt_present("bless"),
diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs
index d723f286fa8..68fe9246602 100644
--- a/src/bootstrap/tool.rs
+++ b/src/bootstrap/tool.rs
@@ -77,7 +77,7 @@ impl Step for ToolBuild {
         let _folder = builder.fold_output(|| format!("stage{}-{}", compiler.stage, tool));
         builder.info(&format!("Building stage{} tool {} ({})", compiler.stage, tool, target));
         let mut duplicates = Vec::new();
-        let is_expected = compile::stream_cargo(builder, &mut cargo, &mut |msg| {
+        let is_expected = compile::stream_cargo(builder, &mut cargo, vec![], &mut |msg| {
             // Only care about big things like the RLS/Cargo for now
             match tool {
                 | "rls"