Skip to content

Commit c268cc0

Browse files
authored
Rollup merge of #77879 - ijackson:x-py, r=jyn514
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.
2 parents 5f5ef05 + 636728e commit c268cc0

File tree

2 files changed

+66
-21
lines changed

2 files changed

+66
-21
lines changed

src/bootstrap/flags.rs

+11-6
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ Subcommands:
125125
dist Build distribution artifacts
126126
install Install distribution artifacts
127127
run, r Run tools contained in this repository
128+
setup Create a config.toml (making it easier to use `x.py` itself)
128129
129130
To learn more about a subcommand, run `./x.py <subcommand> -h`",
130131
);
@@ -472,15 +473,21 @@ Arguments:
472473
);
473474
}
474475
"setup" => {
475-
subcommand_help.push_str(
476+
subcommand_help.push_str(&format!(
476477
"\n
478+
x.py setup creates a `config.toml` which changes the defaults for x.py itself.
479+
477480
Arguments:
478481
This subcommand accepts a 'profile' to use for builds. For example:
479482
480483
./x.py setup library
481484
482-
The profile is optional and you will be prompted interactively if it is not given.",
483-
);
485+
The profile is optional and you will be prompted interactively if it is not given.
486+
The following profiles are available:
487+
488+
{}",
489+
Profile::all_for_help(" ").trim_end()
490+
));
484491
}
485492
_ => {}
486493
};
@@ -551,9 +558,7 @@ Arguments:
551558
profile_string.parse().unwrap_or_else(|err| {
552559
eprintln!("error: {}", err);
553560
eprintln!("help: the available profiles are:");
554-
for choice in Profile::all() {
555-
eprintln!("- {}", choice);
556-
}
561+
eprint!("{}", Profile::all_for_help("- "));
557562
std::process::exit(1);
558563
})
559564
} else {

src/bootstrap/setup.rs

+55-15
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::{t, VERSION};
2+
use std::fmt::Write as _;
23
use std::path::{Path, PathBuf};
34
use std::str::FromStr;
45
use std::{
@@ -20,7 +21,28 @@ impl Profile {
2021
}
2122

2223
pub fn all() -> impl Iterator<Item = Self> {
23-
[Profile::Compiler, Profile::Codegen, Profile::Library, Profile::User].iter().copied()
24+
use Profile::*;
25+
// N.B. these are ordered by how they are displayed, not alphabetically
26+
[Library, Compiler, Codegen, User].iter().copied()
27+
}
28+
29+
pub fn purpose(&self) -> String {
30+
use Profile::*;
31+
match self {
32+
Library => "Contribute to the standard library",
33+
Compiler => "Contribute to the compiler or rustdoc",
34+
Codegen => "Contribute to the compiler, and also modify LLVM or codegen",
35+
User => "Install Rust from source",
36+
}
37+
.to_string()
38+
}
39+
40+
pub fn all_for_help(indent: &str) -> String {
41+
let mut out = String::new();
42+
for choice in Profile::all() {
43+
writeln!(&mut out, "{}{}: {}", indent, choice, choice.purpose()).unwrap();
44+
}
45+
out
2446
}
2547
}
2648

@@ -29,10 +51,10 @@ impl FromStr for Profile {
2951

3052
fn from_str(s: &str) -> Result<Self, Self::Err> {
3153
match s {
32-
"a" | "lib" | "library" => Ok(Profile::Library),
33-
"b" | "compiler" | "rustdoc" => Ok(Profile::Compiler),
34-
"c" | "llvm" | "codegen" => Ok(Profile::Codegen),
35-
"d" | "maintainer" | "user" => Ok(Profile::User),
54+
"lib" | "library" => Ok(Profile::Library),
55+
"compiler" | "rustdoc" => Ok(Profile::Compiler),
56+
"llvm" | "codegen" => Ok(Profile::Codegen),
57+
"maintainer" | "user" => Ok(Profile::User),
3658
_ => Err(format!("unknown profile: '{}'", s)),
3759
}
3860
}
@@ -104,19 +126,37 @@ pub fn setup(src_path: &Path, profile: Profile) {
104126

105127
// Used to get the path for `Subcommand::Setup`
106128
pub fn interactive_path() -> io::Result<Profile> {
107-
let mut input = String::new();
108-
println!(
109-
"Welcome to the Rust project! What do you want to do with x.py?
110-
a) Contribute to the standard library
111-
b) Contribute to the compiler or rustdoc
112-
c) Contribute to the compiler, and also modify LLVM or codegen
113-
d) Install Rust from source"
114-
);
129+
fn abbrev_all() -> impl Iterator<Item = (String, Profile)> {
130+
('a'..).map(|c| c.to_string()).zip(Profile::all())
131+
}
132+
133+
fn parse_with_abbrev(input: &str) -> Result<Profile, String> {
134+
let input = input.trim().to_lowercase();
135+
for (letter, profile) in abbrev_all() {
136+
if input == letter {
137+
return Ok(profile);
138+
}
139+
}
140+
input.parse()
141+
}
142+
143+
println!("Welcome to the Rust project! What do you want to do with x.py?");
144+
for (letter, profile) in abbrev_all() {
145+
println!("{}) {}: {}", letter, profile, profile.purpose());
146+
}
115147
let template = loop {
116-
print!("Please choose one (a/b/c/d): ");
148+
print!(
149+
"Please choose one ({}): ",
150+
abbrev_all().map(|(l, _)| l).collect::<Vec<_>>().join("/")
151+
);
117152
io::stdout().flush()?;
153+
let mut input = String::new();
118154
io::stdin().read_line(&mut input)?;
119-
break match input.trim().to_lowercase().parse() {
155+
if input == "" {
156+
eprintln!("EOF on stdin, when expecting answer to question. Giving up.");
157+
std::process::exit(1);
158+
}
159+
break match parse_with_abbrev(&input) {
120160
Ok(profile) => profile,
121161
Err(err) => {
122162
println!("error: {}", err);

0 commit comments

Comments
 (0)