about summary refs log tree commit diff
path: root/src/bootstrap
diff options
context:
space:
mode:
authorDylan DPC <dylan.dpc@gmail.com>2020-05-22 21:45:00 +0200
committerGitHub <noreply@github.com>2020-05-22 21:45:00 +0200
commit3083ce7ab127dfd1cbb453810579ca827dcfd7bb (patch)
treece8560682a5b1416b63b068651f426f0dccc07be /src/bootstrap
parent01adfe1bc370af0b16265fc6bebbeb9ffe7f459a (diff)
parent07b1de4e9a4a223840efd60475b86f815e84acfa (diff)
downloadrust-3083ce7ab127dfd1cbb453810579ca827dcfd7bb.tar.gz
rust-3083ce7ab127dfd1cbb453810579ca827dcfd7bb.zip
Rollup merge of #72453 - dtolnay:open, r=Mark-Simulacrum
Add flag to open docs:  x.py doc --open

This aligns with Cargo's flag `cargo doc --open`.

Tested with:

```bash
   # opens doc/index.html
x.py doc --stage 0 --open
x.py doc --stage 0 --open src/doc

   # opens doc/book/index.html
x.py doc --stage 0 --open src/doc/book

   # opens doc/std/index.html
x.py doc --stage 0 --open src/libstd

   # opens doc/proc_macro/index.html
x.py doc --stage 0 --open src/libproc_macro

   # opens both
x.py doc --stage 0 --open src/libstd src/libproc_macro
```
Diffstat (limited to 'src/bootstrap')
-rw-r--r--src/bootstrap/Cargo.toml1
-rw-r--r--src/bootstrap/builder.rs2
-rw-r--r--src/bootstrap/doc.rs59
-rw-r--r--src/bootstrap/flags.rs14
4 files changed, 73 insertions, 3 deletions
diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml
index f7856f6a7fc..c4918d7f2e7 100644
--- a/src/bootstrap/Cargo.toml
+++ b/src/bootstrap/Cargo.toml
@@ -48,6 +48,7 @@ toml = "0.5"
 lazy_static = "1.3.0"
 time = "0.1"
 ignore = "0.4.10"
+opener = "0.4"
 
 [target.'cfg(windows)'.dependencies.winapi]
 version = "0.3"
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index 4bc81a7b42d..5489b1bc66b 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -503,7 +503,7 @@ impl<'a> Builder<'a> {
             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::Doc { ref paths, .. } => (Kind::Doc, &paths[..]),
             Subcommand::Test { ref paths, .. } => (Kind::Test, &paths[..]),
             Subcommand::Bench { ref paths, .. } => (Kind::Bench, &paths[..]),
             Subcommand::Dist { ref paths } => (Kind::Dist, &paths[..]),
diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs
index 7eab92ddc92..5c01c5e852c 100644
--- a/src/bootstrap/doc.rs
+++ b/src/bootstrap/doc.rs
@@ -70,6 +70,35 @@ book!(
     RustdocBook, "src/doc/rustdoc", "rustdoc";
 );
 
+fn open(builder: &Builder<'_>, path: impl AsRef<Path>) {
+    if builder.config.dry_run || !builder.config.cmd.open() {
+        return;
+    }
+
+    let path = path.as_ref();
+    builder.info(&format!("Opening doc {}", path.display()));
+    if let Err(err) = opener::open(path) {
+        builder.info(&format!("{}\n", err));
+    }
+}
+
+// "src/libstd" -> ["src", "libstd"]
+//
+// Used for deciding whether a particular step is one requested by the user on
+// the `x.py doc` command line, which determines whether `--open` will open that
+// page.
+fn components_simplified(path: &PathBuf) -> Vec<&str> {
+    path.iter().map(|component| component.to_str().unwrap_or("???")).collect()
+}
+
+fn is_explicit_request(builder: &Builder<'_>, path: &str) -> bool {
+    builder
+        .paths
+        .iter()
+        .map(components_simplified)
+        .any(|requested| requested.iter().copied().eq(path.split("/")))
+}
+
 #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
 pub struct UnstableBook {
     target: Interned<String>,
@@ -200,6 +229,12 @@ impl Step for TheBook {
 
             invoke_rustdoc(builder, compiler, target, path);
         }
+
+        if is_explicit_request(builder, "src/doc/book") {
+            let out = builder.doc_out(target);
+            let index = out.join("book").join("index.html");
+            open(builder, &index);
+        }
     }
 }
 
@@ -338,6 +373,13 @@ impl Step for Standalone {
             }
             builder.run(&mut cmd);
         }
+
+        // We open doc/index.html as the default if invoked as `x.py doc --open`
+        // with no particular explicit doc requested (e.g. src/libcore).
+        if builder.paths.is_empty() || is_explicit_request(builder, "src/doc") {
+            let index = out.join("index.html");
+            open(builder, &index);
+        }
     }
 }
 
@@ -418,10 +460,25 @@ impl Step for Std {
 
             builder.run(&mut cargo.into());
         };
-        for krate in &["alloc", "core", "std", "proc_macro", "test"] {
+        let krates = ["alloc", "core", "std", "proc_macro", "test"];
+        for krate in &krates {
             run_cargo_rustdoc_for(krate);
         }
         builder.cp_r(&my_out, &out);
+
+        // Look for src/libstd, src/libcore etc in the `x.py doc` arguments and
+        // open the corresponding rendered docs.
+        for path in builder.paths.iter().map(components_simplified) {
+            if path.get(0) == Some(&"src")
+                && path.get(1).map_or(false, |dir| dir.starts_with("lib"))
+            {
+                let requested_crate = &path[1][3..];
+                if krates.contains(&requested_crate) {
+                    let index = out.join(requested_crate).join("index.html");
+                    open(builder, &index);
+                }
+            }
+        }
     }
 }
 
diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs
index 646b9e05d99..cfaa43f3970 100644
--- a/src/bootstrap/flags.rs
+++ b/src/bootstrap/flags.rs
@@ -61,6 +61,7 @@ pub enum Subcommand {
     },
     Doc {
         paths: Vec<PathBuf>,
+        open: bool,
     },
     Test {
         paths: Vec<PathBuf>,
@@ -248,6 +249,9 @@ To learn more about a subcommand, run `./x.py <subcommand> -h`",
             "bench" => {
                 opts.optmulti("", "test-args", "extra arguments", "ARGS");
             }
+            "doc" => {
+                opts.optflag("", "open", "open the docs in a browser");
+            }
             "clean" => {
                 opts.optflag("", "all", "clean all build artifacts");
             }
@@ -404,6 +408,7 @@ Arguments:
         ./x.py doc src/doc/book
         ./x.py doc src/doc/nomicon
         ./x.py doc src/doc/book src/libstd
+        ./x.py doc src/libstd --open
 
     If no arguments are passed then everything is documented:
 
@@ -479,7 +484,7 @@ Arguments:
                 },
             },
             "bench" => Subcommand::Bench { paths, test_args: matches.opt_strs("test-args") },
-            "doc" => Subcommand::Doc { paths },
+            "doc" => Subcommand::Doc { paths, open: matches.opt_present("open") },
             "clean" => {
                 if !paths.is_empty() {
                     println!("\nclean does not take a path argument\n");
@@ -613,6 +618,13 @@ impl Subcommand {
             _ => None,
         }
     }
+
+    pub fn open(&self) -> bool {
+        match *self {
+            Subcommand::Doc { open, .. } => open,
+            _ => false,
+        }
+    }
 }
 
 fn split(s: &[String]) -> Vec<String> {