]> git.lizzy.rs Git - rust.git/commitdiff
Rollup merge of #77879 - ijackson:x-py, r=jyn514
authorYuki Okushi <huyuumi.dev@gmail.com>
Wed, 14 Oct 2020 22:32:32 +0000 (07:32 +0900)
committerGitHub <noreply@github.com>
Wed, 14 Oct 2020 22:32:32 +0000 (07:32 +0900)
Provide better documentation and help messages for x.py setup

Closes: #77861
I have split this up into tiny comments because I find it clearer this way.  Feel free to squash it.

src/bootstrap/flags.rs
src/bootstrap/setup.rs

index c10188875fbc4a46779200a8c48f1190c0d4b1f3..22cfd0c56431d878a858c9dae16c840a721fab9f 100644 (file)
@@ -125,6 +125,7 @@ pub fn parse(args: &[String]) -> Flags {
     dist        Build distribution artifacts
     install     Install distribution artifacts
     run, r      Run tools contained in this repository
+    setup       Create a config.toml (making it easier to use `x.py` itself)
 
 To learn more about a subcommand, run `./x.py <subcommand> -h`",
         );
@@ -472,15 +473,21 @@ pub fn parse(args: &[String]) -> Flags {
                 );
             }
             "setup" => {
-                subcommand_help.push_str(
+                subcommand_help.push_str(&format!(
                     "\n
+x.py setup creates a `config.toml` which changes the defaults for x.py itself.
+
 Arguments:
     This subcommand accepts a 'profile' to use for builds. For example:
 
         ./x.py setup library
 
-    The profile is optional and you will be prompted interactively if it is not given.",
-                );
+    The profile is optional and you will be prompted interactively if it is not given.
+    The following profiles are available:
+
+{}",
+                    Profile::all_for_help("        ").trim_end()
+                ));
             }
             _ => {}
         };
@@ -551,9 +558,7 @@ pub fn parse(args: &[String]) -> Flags {
                     profile_string.parse().unwrap_or_else(|err| {
                         eprintln!("error: {}", err);
                         eprintln!("help: the available profiles are:");
-                        for choice in Profile::all() {
-                            eprintln!("- {}", choice);
-                        }
+                        eprint!("{}", Profile::all_for_help("- "));
                         std::process::exit(1);
                     })
                 } else {
index 2a9507cfc4c18b82f7597bdfc4cae651accd654f..a281061ace15b9338fa2428618807652448482c4 100644 (file)
@@ -1,4 +1,5 @@
 use crate::{t, VERSION};
+use std::fmt::Write as _;
 use std::path::{Path, PathBuf};
 use std::str::FromStr;
 use std::{
@@ -20,7 +21,28 @@ fn include_path(&self, src_path: &Path) -> PathBuf {
     }
 
     pub fn all() -> impl Iterator<Item = Self> {
-        [Profile::Compiler, Profile::Codegen, Profile::Library, Profile::User].iter().copied()
+        use Profile::*;
+        // N.B. these are ordered by how they are displayed, not alphabetically
+        [Library, Compiler, Codegen, User].iter().copied()
+    }
+
+    pub fn purpose(&self) -> String {
+        use Profile::*;
+        match self {
+            Library => "Contribute to the standard library",
+            Compiler => "Contribute to the compiler or rustdoc",
+            Codegen => "Contribute to the compiler, and also modify LLVM or codegen",
+            User => "Install Rust from source",
+        }
+        .to_string()
+    }
+
+    pub fn all_for_help(indent: &str) -> String {
+        let mut out = String::new();
+        for choice in Profile::all() {
+            writeln!(&mut out, "{}{}: {}", indent, choice, choice.purpose()).unwrap();
+        }
+        out
     }
 }
 
@@ -29,10 +51,10 @@ impl FromStr for Profile {
 
     fn from_str(s: &str) -> Result<Self, Self::Err> {
         match s {
-            "a" | "lib" | "library" => Ok(Profile::Library),
-            "b" | "compiler" | "rustdoc" => Ok(Profile::Compiler),
-            "c" | "llvm" | "codegen" => Ok(Profile::Codegen),
-            "d" | "maintainer" | "user" => Ok(Profile::User),
+            "lib" | "library" => Ok(Profile::Library),
+            "compiler" | "rustdoc" => Ok(Profile::Compiler),
+            "llvm" | "codegen" => Ok(Profile::Codegen),
+            "maintainer" | "user" => Ok(Profile::User),
             _ => Err(format!("unknown profile: '{}'", s)),
         }
     }
@@ -104,19 +126,37 @@ pub fn setup(src_path: &Path, profile: Profile) {
 
 // Used to get the path for `Subcommand::Setup`
 pub fn interactive_path() -> io::Result<Profile> {
-    let mut input = String::new();
-    println!(
-        "Welcome to the Rust project! What do you want to do with x.py?
-a) Contribute to the standard library
-b) Contribute to the compiler or rustdoc
-c) Contribute to the compiler, and also modify LLVM or codegen
-d) Install Rust from source"
-    );
+    fn abbrev_all() -> impl Iterator<Item = (String, Profile)> {
+        ('a'..).map(|c| c.to_string()).zip(Profile::all())
+    }
+
+    fn parse_with_abbrev(input: &str) -> Result<Profile, String> {
+        let input = input.trim().to_lowercase();
+        for (letter, profile) in abbrev_all() {
+            if input == letter {
+                return Ok(profile);
+            }
+        }
+        input.parse()
+    }
+
+    println!("Welcome to the Rust project! What do you want to do with x.py?");
+    for (letter, profile) in abbrev_all() {
+        println!("{}) {}: {}", letter, profile, profile.purpose());
+    }
     let template = loop {
-        print!("Please choose one (a/b/c/d): ");
+        print!(
+            "Please choose one ({}): ",
+            abbrev_all().map(|(l, _)| l).collect::<Vec<_>>().join("/")
+        );
         io::stdout().flush()?;
+        let mut input = String::new();
         io::stdin().read_line(&mut input)?;
-        break match input.trim().to_lowercase().parse() {
+        if input == "" {
+            eprintln!("EOF on stdin, when expecting answer to question.  Giving up.");
+            std::process::exit(1);
+        }
+        break match parse_with_abbrev(&input) {
             Ok(profile) => profile,
             Err(err) => {
                 println!("error: {}", err);