about summary refs log tree commit diff
path: root/src/bootstrap
diff options
context:
space:
mode:
authorIan Jackson <ijackson@chiark.greenend.org.uk>2020-10-13 00:07:52 +0100
committerIan Jackson <ijackson@chiark.greenend.org.uk>2020-10-14 11:40:53 +0100
commitc4c5653a48fa6871bf2a07dd56cb7f2801115bfb (patch)
treef61d224fec48e30ac3c1c58bf6ed78ab8a8a3575 /src/bootstrap
parent5565241f65cf402c3dbcb55dd492f172c473d4ce (diff)
downloadrust-c4c5653a48fa6871bf2a07dd56cb7f2801115bfb.tar.gz
rust-c4c5653a48fa6871bf2a07dd56cb7f2801115bfb.zip
x.py: setup: Refactor to centralise list of profiles
Put all()'s otuput in the order we want to print things in, and add a
comment about why they are in this order.  Provide purpose() and
all_for_help().  Use these things everywhere.

Move all the abbrev character ("a", "b", etc.) processing into
interactive_path.

No functional change.

Signed-off-by: Ian Jackson <ijackson@chiark.greenend.org.uk>
Diffstat (limited to 'src/bootstrap')
-rw-r--r--src/bootstrap/flags.rs4
-rw-r--r--src/bootstrap/setup.rs64
2 files changed, 51 insertions, 17 deletions
diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs
index c10188875fb..f38c6876747 100644
--- a/src/bootstrap/flags.rs
+++ b/src/bootstrap/flags.rs
@@ -551,9 +551,7 @@ Arguments:
                     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 {
diff --git a/src/bootstrap/setup.rs b/src/bootstrap/setup.rs
index 2a9507cfc4c..85b361e16a3 100644
--- a/src/bootstrap/setup.rs
+++ b/src/bootstrap/setup.rs
@@ -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 @@ impl Profile {
     }
 
     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).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,33 @@ pub fn setup(src_path: &Path, profile: Profile) {
 
 // Used to get the path for `Subcommand::Setup`
 pub fn interactive_path() -> io::Result<Profile> {
+    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()
+    }
+
     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"
-    );
+    println!("Welcome to the Rust project! What do you want to do with x.py?");
+    for (letter, profile) in abbrev_all() {
+        println!("{}) {}", letter, 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()?;
         io::stdin().read_line(&mut input)?;
-        break match input.trim().to_lowercase().parse() {
+        break match parse_with_abbrev(&input) {
             Ok(profile) => profile,
             Err(err) => {
                 println!("error: {}", err);