Skip to content

Commit 3fb5d8e

Browse files
authored
Rollup merge of #96584 - bentongxyz:x-setup-h-v-should-work, r=jyn514
Fix `x setup -h -v` should work r? `@jyn514` I have to convert profile to path and back in order to remove special-casing in bootstrap. I also check for `dry_run` so that `config.toml` and/ or `.git/hooks/pre-push` will not be created if `--dry-run` is specified. Please help me see if this is ok, thanks alot!
2 parents 35a99ee + fca8290 commit 3fb5d8e

File tree

4 files changed

+74
-21
lines changed

4 files changed

+74
-21
lines changed

src/bootstrap/builder.rs

+12-3
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use crate::flags::{Color, Subcommand};
1919
use crate::install;
2020
use crate::native;
2121
use crate::run;
22+
use crate::setup;
2223
use crate::test;
2324
use crate::tool::{self, SourceType};
2425
use crate::util::{self, add_dylib_path, add_link_lib_path, exe, libdir, output, t};
@@ -433,8 +434,11 @@ impl<'a> ShouldRun<'a> {
433434

434435
// single alias, which does not correspond to any on-disk path
435436
pub fn alias(mut self, alias: &str) -> Self {
437+
// exceptional case for `Kind::Setup` because its `library`
438+
// and `compiler` options would otherwise naively match with
439+
// `compiler` and `library` folders respectively.
436440
assert!(
437-
!self.builder.src.join(alias).exists(),
441+
self.kind == Kind::Setup || !self.builder.src.join(alias).exists(),
438442
"use `builder.path()` for real paths: {}",
439443
alias
440444
);
@@ -758,8 +762,9 @@ impl<'a> Builder<'a> {
758762
run::CollectLicenseMetadata,
759763
run::GenerateCopyright,
760764
),
765+
Kind::Setup => describe!(setup::Profile),
761766
// These commands either don't use paths, or they're special-cased in Build::build()
762-
Kind::Clean | Kind::Format | Kind::Setup => vec![],
767+
Kind::Clean | Kind::Format => vec![],
763768
}
764769
}
765770

@@ -822,7 +827,11 @@ impl<'a> Builder<'a> {
822827
Subcommand::Install { ref paths } => (Kind::Install, &paths[..]),
823828
Subcommand::Run { ref paths, .. } => (Kind::Run, &paths[..]),
824829
Subcommand::Format { .. } => (Kind::Format, &[][..]),
825-
Subcommand::Clean { .. } | Subcommand::Setup { .. } => {
830+
Subcommand::Setup { profile: ref path } => (
831+
Kind::Setup,
832+
path.as_ref().map_or([].as_slice(), |path| std::slice::from_ref(path)),
833+
),
834+
Subcommand::Clean { .. } => {
826835
panic!()
827836
}
828837
};

src/bootstrap/flags.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ pub enum Subcommand {
143143
args: Vec<String>,
144144
},
145145
Setup {
146-
profile: Option<Profile>,
146+
profile: Option<PathBuf>,
147147
},
148148
}
149149

@@ -351,7 +351,7 @@ To learn more about a subcommand, run `./x.py <subcommand> -h`",
351351

352352
// fn usage()
353353
let usage = |exit_code: i32, opts: &Options, verbose: bool, subcommand_help: &str| -> ! {
354-
let config = Config::parse(&["build".to_string()]);
354+
let config = Config::parse(&["setup".to_string()]);
355355
let build = Build::new(config);
356356
let paths = Builder::get_help(&build, subcommand);
357357

@@ -621,7 +621,7 @@ Arguments:
621621
}
622622
Kind::Setup => {
623623
let profile = if paths.len() > 1 {
624-
println!("\nat most one profile can be passed to setup\n");
624+
eprintln!("\nerror: At most one profile can be passed to setup\n");
625625
usage(1, &opts, verbose, &subcommand_help)
626626
} else if let Some(path) = paths.pop() {
627627
let profile_string = t!(path.into_os_string().into_string().map_err(

src/bootstrap/lib.rs

-4
Original file line numberDiff line numberDiff line change
@@ -730,10 +730,6 @@ impl Build {
730730
return clean::clean(self, all);
731731
}
732732

733-
if let Subcommand::Setup { profile } = &self.config.cmd {
734-
return setup::setup(&self.config, *profile);
735-
}
736-
737733
// Download rustfmt early so that it can be used in rust-analyzer configs.
738734
let _ = &builder::Builder::new(&self).initial_rustfmt();
739735

src/bootstrap/setup.rs

+59-11
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use crate::builder::{Builder, RunConfig, ShouldRun, Step};
12
use crate::Config;
23
use crate::{t, VERSION};
34
use std::env::consts::EXE_SUFFIX;
@@ -9,7 +10,7 @@ use std::process::Command;
910
use std::str::FromStr;
1011
use std::{fmt, fs, io};
1112

12-
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
13+
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
1314
pub enum Profile {
1415
Compiler,
1516
Codegen,
@@ -48,6 +49,16 @@ impl Profile {
4849
}
4950
out
5051
}
52+
53+
pub fn as_str(&self) -> &'static str {
54+
match self {
55+
Profile::Compiler => "compiler",
56+
Profile::Codegen => "codegen",
57+
Profile::Library => "library",
58+
Profile::Tools => "tools",
59+
Profile::User => "user",
60+
}
61+
}
5162
}
5263

5364
impl FromStr for Profile {
@@ -69,24 +80,58 @@ impl FromStr for Profile {
6980

7081
impl fmt::Display for Profile {
7182
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
72-
match self {
73-
Profile::Compiler => write!(f, "compiler"),
74-
Profile::Codegen => write!(f, "codegen"),
75-
Profile::Library => write!(f, "library"),
76-
Profile::User => write!(f, "user"),
77-
Profile::Tools => write!(f, "tools"),
83+
f.write_str(self.as_str())
84+
}
85+
}
86+
87+
impl Step for Profile {
88+
type Output = ();
89+
const DEFAULT: bool = true;
90+
91+
fn should_run(mut run: ShouldRun<'_>) -> ShouldRun<'_> {
92+
for choice in Profile::all() {
93+
run = run.alias(choice.as_str());
7894
}
95+
run
96+
}
97+
98+
fn make_run(run: RunConfig<'_>) {
99+
// for Profile, `run.paths` will have 1 and only 1 element
100+
// this is because we only accept at most 1 path from user input.
101+
// If user calls `x.py setup` without arguments, the interactive TUI
102+
// will guide user to provide one.
103+
let profile = if run.paths.len() > 1 {
104+
// HACK: `builder` runs this step with all paths if no path was passed.
105+
t!(interactive_path())
106+
} else {
107+
run.paths
108+
.first()
109+
.unwrap()
110+
.assert_single_path()
111+
.path
112+
.as_path()
113+
.as_os_str()
114+
.to_str()
115+
.unwrap()
116+
.parse()
117+
.unwrap()
118+
};
119+
120+
run.builder.ensure(profile);
121+
}
122+
123+
fn run(self, builder: &Builder<'_>) {
124+
setup(&builder.build.config, self)
79125
}
80126
}
81127

82-
pub fn setup(config: &Config, profile: Option<Profile>) {
83-
let profile = profile.unwrap_or_else(|| t!(interactive_path()));
128+
pub fn setup(config: &Config, profile: Profile) {
84129
let stage_path =
85130
["build", config.build.rustc_target_arg(), "stage1"].join(&MAIN_SEPARATOR.to_string());
86131

87132
if !rustup_installed() && profile != Profile::User {
88133
eprintln!("`rustup` is not installed; cannot link `stage1` toolchain");
89-
} else if stage_dir_exists(&stage_path[..]) {
134+
} else if stage_dir_exists(&stage_path[..]) && !config.dry_run() {
90135
attempt_toolchain_link(&stage_path[..]);
91136
}
92137

@@ -104,7 +149,9 @@ pub fn setup(config: &Config, profile: Option<Profile>) {
104149
Profile::User => &["dist", "build"],
105150
};
106151

107-
t!(install_git_hook_maybe(&config));
152+
if !config.dry_run() {
153+
t!(install_git_hook_maybe(&config));
154+
}
108155

109156
println!();
110157

@@ -144,6 +191,7 @@ fn setup_config_toml(path: &PathBuf, profile: Profile, config: &Config) {
144191
changelog-seen = {}\n",
145192
profile, VERSION
146193
);
194+
147195
t!(fs::write(path, settings));
148196

149197
let include_path = profile.include_path(&config.src);

0 commit comments

Comments
 (0)