summary refs log tree commit diff
path: root/src/bootstrap/builder.rs
diff options
context:
space:
mode:
authorMark Simulacrum <mark.simulacrum@gmail.com>2017-07-18 18:03:38 -0600
committerMark Simulacrum <mark.simulacrum@gmail.com>2017-07-20 11:24:37 -0600
commit56128fb3acdbb40876d1fc8aee613792ebef3080 (patch)
treec8753059843a319610a541faa01b990a0aac6e0f /src/bootstrap/builder.rs
parentbca1e2ffd1658e800e15e730dee5d6cc02722270 (diff)
downloadrust-56128fb3acdbb40876d1fc8aee613792ebef3080.tar.gz
rust-56128fb3acdbb40876d1fc8aee613792ebef3080.zip
Implement available paths list.
Diffstat (limited to 'src/bootstrap/builder.rs')
-rw-r--r--src/bootstrap/builder.rs105
1 files changed, 98 insertions, 7 deletions
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index 77f8dda251b..8613bc7a7ba 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -16,6 +16,7 @@ use std::process::Command;
 use std::fs;
 use std::ops::Deref;
 use std::any::Any;
+use std::collections::BTreeSet;
 
 use compile;
 use install;
@@ -70,7 +71,7 @@ pub trait Step: 'static + Clone + Debug + PartialEq + Eq + Hash {
     /// will execute. However, it does not get called in a "default" context
     /// when we are not passed any paths; in that case, make_run is called
     /// directly.
-    fn should_run(builder: &Builder, path: &Path) -> bool;
+    fn should_run(run: ShouldRun) -> ShouldRun;
 
     /// Build up a "root" rule, either as a default rule or from a path passed
     /// to us.
@@ -92,6 +93,43 @@ pub trait Step: 'static + Clone + Debug + PartialEq + Eq + Hash {
     }
 }
 
+#[derive(Clone)]
+pub struct ShouldRun<'a> {
+    builder: &'a Builder<'a>,
+    // use a BTreeSet to maintain sort order
+    paths: BTreeSet<PathBuf>,
+}
+
+impl<'a> ShouldRun<'a> {
+    fn new(builder: &'a Builder) -> ShouldRun<'a> {
+        ShouldRun {
+            builder: builder,
+            paths: BTreeSet::new(),
+        }
+    }
+
+    pub fn krate(mut self, name: &str) -> Self {
+        for (_, krate_path) in self.builder.crates(name) {
+            self.paths.insert(PathBuf::from(krate_path));
+        }
+        self
+    }
+
+    pub fn path(mut self, path: &str) -> Self {
+        self.paths.insert(PathBuf::from(path));
+        self
+    }
+
+    // allows being more explicit about why should_run in Step returns the value passed to it
+    pub fn never(self) -> ShouldRun<'a> {
+        self
+    }
+
+    fn run(&self, path: &Path) -> bool {
+        self.paths.iter().any(|p| path.ends_with(p))
+    }
+}
+
 #[derive(Copy, Clone, PartialEq, Eq, Debug)]
 pub enum Kind {
     Build,
@@ -115,7 +153,7 @@ macro_rules! check {
             for path in paths {
                 let mut attempted_run = false;
                 $({
-                    if <$rule>::should_run($self, path) {
+                    if <$rule>::should_run(ShouldRun::new($self)).run(path) {
                         attempted_run = true;
                         $self.maybe_run::<$rule>(Some(path));
                     }
@@ -129,6 +167,60 @@ macro_rules! check {
 }
 
 impl<'a> Builder<'a> {
+    pub fn get_help(build: &Build, subcommand: &str) -> Option<String> {
+        let kind = match subcommand {
+            "build" => Kind::Build,
+            "doc" => Kind::Doc,
+            "test" => Kind::Test,
+            "bench" => Kind::Bench,
+            "dist" => Kind::Dist,
+            "install" => Kind::Install,
+            _ => return None,
+        };
+
+        let builder = Builder {
+            build: build,
+            top_stage: build.flags.stage.unwrap_or(2),
+            kind: kind,
+            cache: Cache::new(),
+            stack: RefCell::new(Vec::new()),
+        };
+
+        let builder = &builder;
+        let mut should_run = ShouldRun::new(builder);
+        macro_rules! into_shouldrun {
+            ($should_run:ident, $($rule:ty),+ $(,)*) => {{
+                $(
+                    $should_run = <$rule>::should_run($should_run);
+                )+
+            }};
+        }
+        match builder.kind {
+            Kind::Build => into_shouldrun!(should_run, compile::Std, compile::Test, compile::Rustc,
+                compile::StartupObjects, tool::BuildManifest, tool::Rustbook, tool::ErrorIndex,
+                tool::UnstableBookGen, tool::Tidy, tool::Linkchecker, tool::CargoTest,
+                tool::Compiletest, tool::RemoteTestServer, tool::RemoteTestClient,
+                tool::RustInstaller, tool::Cargo, tool::Rls),
+            Kind::Test => into_shouldrun!(should_run, check::Tidy, check::Bootstrap,
+                check::Compiletest, check::Crate, check::CrateLibrustc, check::Linkcheck,
+                check::Cargotest, check::Cargo, check::Docs, check::ErrorIndex, check::Distcheck),
+            Kind::Bench => into_shouldrun!(should_run, check::Crate, check::CrateLibrustc),
+            Kind::Doc => into_shouldrun!(should_run, doc::UnstableBook, doc::UnstableBookGen,
+                doc::TheBook, doc::Standalone, doc::Std, doc::Test, doc::Rustc, doc::ErrorIndex,
+                doc::Nomicon, doc::Reference),
+            Kind::Dist => into_shouldrun!(should_run, dist::Docs, dist::Mingw, dist::Rustc,
+                dist::DebuggerScripts, dist::Std, dist::Analysis, dist::Src,
+                dist::PlainSourceTarball, dist::Cargo, dist::Rls, dist::Extended, dist::HashSign),
+            Kind::Install => into_shouldrun!(should_run, install::Docs, install::Std,
+                install::Cargo, install::Rls, install::Analysis, install::Src, install::Rustc),
+        }
+        let mut help = String::from("Available paths:\n");
+        for path in should_run.paths {
+            help.push_str(format!("    ./x.py {} {}\n", subcommand, path.display()).as_str());
+        }
+        Some(help)
+    }
+
     pub fn run(build: &Build) {
         let (kind, paths) = match build.flags.cmd {
             Subcommand::Build { ref paths } => (Kind::Build, &paths[..]),
@@ -170,9 +262,8 @@ impl<'a> Builder<'a> {
 
     pub fn default_doc(&self, paths: Option<&[PathBuf]>) {
         let paths = paths.unwrap_or(&[]);
-        check!(self, paths, doc::UnstableBook, doc::UnstableBookGen, doc::Rustbook, doc::TheBook,
-            doc::Standalone, doc::Std, doc::Test, doc::Rustc, doc::ErrorIndex,
-            doc::Nomicon, doc::Reference);
+        check!(self, paths, doc::UnstableBook, doc::UnstableBookGen, doc::TheBook, doc::Standalone,
+            doc::Std, doc::Test, doc::Rustc, doc::ErrorIndex, doc::Nomicon, doc::Reference);
     }
 
     /// Obtain a compiler at a given stage and for a given host. Explictly does
@@ -200,8 +291,8 @@ impl<'a> Builder<'a> {
         impl Step for Libdir {
             type Output = Interned<PathBuf>;
 
-            fn should_run(_builder: &Builder, _path: &Path) -> bool {
-                false
+            fn should_run(run: ShouldRun) -> ShouldRun {
+                run.never()
             }
 
             fn run(self, builder: &Builder) -> Interned<PathBuf> {