about summary refs log tree commit diff
path: root/src/bootstrap
diff options
context:
space:
mode:
authorkennytm <kennytm@gmail.com>2017-11-30 18:18:47 +0800
committerkennytm <kennytm@gmail.com>2017-12-03 18:36:56 +0800
commit971b1ba42bcb318baf31047cf80a4cf532756ec8 (patch)
tree067132d0ba595ab165b52c608f6567469c625792 /src/bootstrap
parent128199e39c2644e3e0c0580869a561f9211e6d98 (diff)
downloadrust-971b1ba42bcb318baf31047cf80a4cf532756ec8.tar.gz
rust-971b1ba42bcb318baf31047cf80a4cf532756ec8.zip
Record build and test result of extended tools into toolstates.json.
Diffstat (limited to 'src/bootstrap')
-rw-r--r--src/bootstrap/check.rs30
-rw-r--r--src/bootstrap/config.rs4
-rwxr-xr-xsrc/bootstrap/configure.py1
-rw-r--r--src/bootstrap/lib.rs25
-rw-r--r--src/bootstrap/tool.rs14
-rw-r--r--src/bootstrap/toolstate.rs2
6 files changed, 64 insertions, 12 deletions
diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs
index 103d7f2ba18..8f3133bc9d8 100644
--- a/src/bootstrap/check.rs
+++ b/src/bootstrap/check.rs
@@ -65,19 +65,21 @@ impl fmt::Display for TestKind {
     }
 }
 
-fn try_run_expecting(build: &Build, cmd: &mut Command, expect: BuildExpectation) {
+fn try_run_expecting(build: &Build, cmd: &mut Command, expect: BuildExpectation) -> bool {
     if !build.fail_fast {
         if !build.try_run(cmd, expect) {
             let mut failures = build.delayed_failures.borrow_mut();
             failures.push(format!("{:?}", cmd));
+            return false;
         }
     } else {
         build.run_expecting(cmd, expect);
     }
+    true
 }
 
 fn try_run(build: &Build, cmd: &mut Command) {
-    try_run_expecting(build, cmd, BuildExpectation::None)
+    try_run_expecting(build, cmd, BuildExpectation::None);
 }
 
 fn try_run_quiet(build: &Build, cmd: &mut Command) {
@@ -257,11 +259,13 @@ impl Step for Rls {
 
         builder.add_rustc_lib_path(compiler, &mut cargo);
 
-        try_run_expecting(
+        if try_run_expecting(
             build,
             &mut cargo,
             builder.build.config.toolstate.rls.passes(ToolState::Testing),
-        );
+        ) {
+            build.save_toolstate("rls", ToolState::Testing);
+        }
     }
 }
 
@@ -305,11 +309,13 @@ impl Step for Rustfmt {
 
         builder.add_rustc_lib_path(compiler, &mut cargo);
 
-        try_run_expecting(
+        if try_run_expecting(
             build,
             &mut cargo,
             builder.build.config.toolstate.rustfmt.passes(ToolState::Testing),
-        );
+        ) {
+            build.save_toolstate("rustfmt", ToolState::Testing);
+        }
     }
 }
 
@@ -354,11 +360,13 @@ impl Step for Miri {
 
             builder.add_rustc_lib_path(compiler, &mut cargo);
 
-            try_run_expecting(
+            if try_run_expecting(
                 build,
                 &mut cargo,
                 builder.build.config.toolstate.miri.passes(ToolState::Testing),
-            );
+            ) {
+                build.save_toolstate("miri", ToolState::Testing);
+            }
         } else {
             eprintln!("failed to test miri: could not build");
         }
@@ -411,11 +419,13 @@ impl Step for Clippy {
 
             builder.add_rustc_lib_path(compiler, &mut cargo);
 
-            try_run_expecting(
+            if try_run_expecting(
                 build,
                 &mut cargo,
                 builder.build.config.toolstate.clippy.passes(ToolState::Testing),
-            );
+            ) {
+                build.save_toolstate("clippy-driver", ToolState::Testing);
+            }
         } else {
             eprintln!("failed to test clippy: could not build");
         }
diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs
index d43cd54ddce..9dd37d8e456 100644
--- a/src/bootstrap/config.rs
+++ b/src/bootstrap/config.rs
@@ -112,6 +112,8 @@ pub struct Config {
     pub channel: String,
     pub quiet_tests: bool,
     pub test_miri: bool,
+    pub save_toolstates: Option<PathBuf>,
+
     // Fallback musl-root for all targets
     pub musl_root: Option<PathBuf>,
     pub prefix: Option<PathBuf>,
@@ -279,6 +281,7 @@ struct Rust {
     dist_src: Option<bool>,
     quiet_tests: Option<bool>,
     test_miri: Option<bool>,
+    save_toolstates: Option<String>,
 }
 
 /// TOML representation of how each build target is configured.
@@ -473,6 +476,7 @@ impl Config {
             set(&mut config.test_miri, rust.test_miri);
             config.rustc_default_linker = rust.default_linker.clone();
             config.musl_root = rust.musl_root.clone().map(PathBuf::from);
+            config.save_toolstates = rust.save_toolstates.clone().map(PathBuf::from);
 
             match rust.codegen_units {
                 Some(0) => config.rust_codegen_units = Some(num_cpus::get() as u32),
diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py
index 579422c9799..48ca2838e4f 100755
--- a/src/bootstrap/configure.py
+++ b/src/bootstrap/configure.py
@@ -77,6 +77,7 @@ o("debuginfo", "rust.debuginfo", "build with debugger metadata")
 o("debuginfo-lines", "rust.debuginfo-lines", "build with line number debugger metadata")
 o("debuginfo-only-std", "rust.debuginfo-only-std", "build only libstd with debugging information")
 o("debug-jemalloc", "rust.debug-jemalloc", "build jemalloc with --enable-debug --enable-fill")
+v("save-toolstates", "rust.save-toolstates", "save build and test status of external tools into this file")
 
 v("prefix", "install.prefix", "set installation prefix")
 v("localstatedir", "install.localstatedir", "local state directory")
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index 68329922592..2f00c313a0c 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -190,6 +190,7 @@ mod job {
 pub use config::Config;
 use flags::Subcommand;
 use cache::{Interned, INTERNER};
+use toolstate::ToolState;
 
 /// A structure representing a Rust compiler.
 ///
@@ -874,6 +875,30 @@ impl Build {
         }
     }
 
+    /// Updates the actual toolstate of a tool.
+    ///
+    /// The toolstates are saved to the file specified by the key
+    /// `rust.save-toolstates` in `config.toml`. If unspecified, nothing will be
+    /// done. The file is updated immediately after this function completes.
+    pub fn save_toolstate(&self, tool: &str, state: ToolState) {
+        use std::io::{Seek, SeekFrom};
+
+        if let Some(ref path) = self.config.save_toolstates {
+            let mut file = t!(fs::OpenOptions::new()
+                .create(true)
+                .read(true)
+                .write(true)
+                .open(path));
+
+            let mut current_toolstates: HashMap<Box<str>, ToolState> =
+                serde_json::from_reader(&mut file).unwrap_or_default();
+            current_toolstates.insert(tool.into(), state);
+            t!(file.seek(SeekFrom::Start(0)));
+            t!(file.set_len(0));
+            t!(serde_json::to_writer(file, &current_toolstates));
+        }
+    }
+
     /// Get a list of crates from a root crate.
     ///
     /// Returns Vec<(crate, path to crate, is_root_crate)>
diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs
index fe1c8292340..fa9bdc43c37 100644
--- a/src/bootstrap/tool.rs
+++ b/src/bootstrap/tool.rs
@@ -115,7 +115,19 @@ impl Step for ToolBuild {
         println!("Building stage{} tool {} ({})", compiler.stage, tool, target);
 
         let mut cargo = prepare_tool_cargo(builder, compiler, target, "build", path);
-        if !build.try_run(&mut cargo, expectation) {
+        let is_expected = build.try_run(&mut cargo, expectation);
+        // If the expectation is "Failing", `try_run` returning true actually
+        // means a build-failure is successfully observed, i.e. the tool is
+        // broken. Thus the XOR here.
+        // Sorry for the complicated logic, but we can remove this expectation
+        // logic after #45861 is fully fixed.
+        build.save_toolstate(tool, if is_expected ^ (expectation == BuildExpectation::Failing) {
+            ToolState::Compiling
+        } else {
+            ToolState::Broken
+        });
+
+        if !is_expected {
             if expectation == BuildExpectation::None {
                 exit(1);
             } else {
diff --git a/src/bootstrap/toolstate.rs b/src/bootstrap/toolstate.rs
index 328cbf0e5d7..00dbcc86af4 100644
--- a/src/bootstrap/toolstate.rs
+++ b/src/bootstrap/toolstate.rs
@@ -10,7 +10,7 @@
 
 use build_helper::BuildExpectation;
 
-#[derive(Copy, Clone, Debug, Deserialize, PartialEq, Eq)]
+#[derive(Copy, Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
 /// Whether a tool can be compiled, tested or neither
 pub enum ToolState {
     /// The tool compiles successfully, but the test suite fails