about summary refs log tree commit diff
diff options
context:
space:
mode:
authorYuki Okushi <jtitor@2k36.org>2021-06-21 09:42:15 +0900
committerGitHub <noreply@github.com>2021-06-21 09:42:15 +0900
commite7a4f1e3fcb9af6841a07f073432b838193550d4 (patch)
tree2e946f1ab83131e2ef09f8721377199b34a9ccf9
parente6732e05e4ff7af66084bf2c212a7fbf1ec6a574 (diff)
parentbde95700691cad1c508eb396e190a9d8638f024f (diff)
downloadrust-e7a4f1e3fcb9af6841a07f073432b838193550d4.tar.gz
rust-e7a4f1e3fcb9af6841a07f073432b838193550d4.zip
Rollup merge of #86152 - the8472:lazify-npm-queries, r=Mark-Simulacrum
Lazify is_really_default condition in the RustdocGUI bootstrap step

The `RustdocGUI::should_run` condition spawns `npm list` several times which adds up to seconds of wall-time.
Evaluate the condition lazily to to keep `./x.py test tidy` and similar short-running tasks fast.

Fixes #86147
-rw-r--r--Cargo.lock1
-rw-r--r--src/bootstrap/Cargo.toml1
-rw-r--r--src/bootstrap/builder.rs28
-rw-r--r--src/bootstrap/test.rs6
4 files changed, 28 insertions, 8 deletions
diff --git a/Cargo.lock b/Cargo.lock
index bc8b79342b2..5e2987ee826 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -179,6 +179,7 @@ dependencies = [
  "libc",
  "merge",
  "num_cpus",
+ "once_cell",
  "opener",
  "pretty_assertions",
  "serde",
diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml
index 8445d811e0f..d1e666936f8 100644
--- a/src/bootstrap/Cargo.toml
+++ b/src/bootstrap/Cargo.toml
@@ -50,6 +50,7 @@ time = "0.1"
 ignore = "0.4.10"
 opener = "0.4"
 merge = "0.1.0"
+once_cell = "1.7.2"
 
 [target.'cfg(windows)'.dependencies.winapi]
 version = "0.3"
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index bc499fdba59..e2f605257bd 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -29,6 +29,8 @@ use crate::util::{self, add_dylib_path, add_link_lib_path, exe, libdir};
 use crate::{Build, DocTests, GitRepo, Mode};
 
 pub use crate::Compiler;
+// FIXME: replace with std::lazy after it gets stabilized and reaches beta
+use once_cell::sync::Lazy;
 
 pub struct Builder<'a> {
     pub build: &'a Build,
@@ -195,7 +197,7 @@ impl StepDescription {
 
         if paths.is_empty() || builder.config.include_default_paths {
             for (desc, should_run) in v.iter().zip(&should_runs) {
-                if desc.default && should_run.is_really_default {
+                if desc.default && should_run.is_really_default() {
                     for pathset in &should_run.paths {
                         desc.maybe_run(builder, pathset);
                     }
@@ -228,7 +230,11 @@ impl StepDescription {
     }
 }
 
-#[derive(Clone)]
+enum ReallyDefault<'a> {
+    Bool(bool),
+    Lazy(Lazy<bool, Box<dyn Fn() -> bool + 'a>>),
+}
+
 pub struct ShouldRun<'a> {
     pub builder: &'a Builder<'a>,
     // use a BTreeSet to maintain sort order
@@ -236,7 +242,7 @@ pub struct ShouldRun<'a> {
 
     // If this is a default rule, this is an additional constraint placed on
     // its run. Generally something like compiler docs being enabled.
-    is_really_default: bool,
+    is_really_default: ReallyDefault<'a>,
 }
 
 impl<'a> ShouldRun<'a> {
@@ -244,15 +250,27 @@ impl<'a> ShouldRun<'a> {
         ShouldRun {
             builder,
             paths: BTreeSet::new(),
-            is_really_default: true, // by default no additional conditions
+            is_really_default: ReallyDefault::Bool(true), // by default no additional conditions
         }
     }
 
     pub fn default_condition(mut self, cond: bool) -> Self {
-        self.is_really_default = cond;
+        self.is_really_default = ReallyDefault::Bool(cond);
+        self
+    }
+
+    pub fn lazy_default_condition(mut self, lazy_cond: Box<dyn Fn() -> bool + 'a>) -> Self {
+        self.is_really_default = ReallyDefault::Lazy(Lazy::new(lazy_cond));
         self
     }
 
+    pub fn is_really_default(&self) -> bool {
+        match &self.is_really_default {
+            ReallyDefault::Bool(val) => *val,
+            ReallyDefault::Lazy(lazy) => *lazy.deref(),
+        }
+    }
+
     /// Indicates it should run if the command-line selects the given crate or
     /// any of its (local) dependencies.
     ///
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index 0b7a0e25df1..319b56a0b70 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -806,15 +806,15 @@ impl Step for RustdocGUI {
     fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
         let builder = run.builder;
         let run = run.suite_path("src/test/rustdoc-gui");
-        run.default_condition(
+        run.lazy_default_condition(Box::new(move || {
             builder.config.nodejs.is_some()
                 && builder
                     .config
                     .npm
                     .as_ref()
                     .map(|p| check_if_browser_ui_test_is_installed(p))
-                    .unwrap_or(false),
-        )
+                    .unwrap_or(false)
+        }))
     }
 
     fn make_run(run: RunConfig<'_>) {