Remove special cases for setup subcommand
- Remove setup special-casing in Flags::parse
This commit is contained in:
parent
2d76a9df5d
commit
fca829075f
@ -19,6 +19,7 @@
|
||||
use crate::install;
|
||||
use crate::native;
|
||||
use crate::run;
|
||||
use crate::setup;
|
||||
use crate::test;
|
||||
use crate::tool::{self, SourceType};
|
||||
use crate::util::{self, add_dylib_path, add_link_lib_path, exe, libdir, output, t};
|
||||
@ -433,8 +434,11 @@ pub(crate) fn crates(mut self, crates: Vec<&Crate>) -> Self {
|
||||
|
||||
// single alias, which does not correspond to any on-disk path
|
||||
pub fn alias(mut self, alias: &str) -> Self {
|
||||
// exceptional case for `Kind::Setup` because its `library`
|
||||
// and `compiler` options would otherwise naively match with
|
||||
// `compiler` and `library` folders respectively.
|
||||
assert!(
|
||||
!self.builder.src.join(alias).exists(),
|
||||
self.kind == Kind::Setup || !self.builder.src.join(alias).exists(),
|
||||
"use `builder.path()` for real paths: {}",
|
||||
alias
|
||||
);
|
||||
@ -757,8 +761,9 @@ macro_rules! describe {
|
||||
run::CollectLicenseMetadata,
|
||||
run::GenerateCopyright,
|
||||
),
|
||||
Kind::Setup => describe!(setup::Profile),
|
||||
// These commands either don't use paths, or they're special-cased in Build::build()
|
||||
Kind::Clean | Kind::Format | Kind::Setup => vec![],
|
||||
Kind::Clean | Kind::Format => vec![],
|
||||
}
|
||||
}
|
||||
|
||||
@ -821,7 +826,11 @@ pub fn new(build: &Build) -> Builder<'_> {
|
||||
Subcommand::Install { ref paths } => (Kind::Install, &paths[..]),
|
||||
Subcommand::Run { ref paths, .. } => (Kind::Run, &paths[..]),
|
||||
Subcommand::Format { .. } => (Kind::Format, &[][..]),
|
||||
Subcommand::Clean { .. } | Subcommand::Setup { .. } => {
|
||||
Subcommand::Setup { profile: ref path } => (
|
||||
Kind::Setup,
|
||||
path.as_ref().map_or([].as_slice(), |path| std::slice::from_ref(path)),
|
||||
),
|
||||
Subcommand::Clean { .. } => {
|
||||
panic!()
|
||||
}
|
||||
};
|
||||
|
@ -143,7 +143,7 @@ pub enum Subcommand {
|
||||
args: Vec<String>,
|
||||
},
|
||||
Setup {
|
||||
profile: Option<Profile>,
|
||||
profile: Option<PathBuf>,
|
||||
},
|
||||
}
|
||||
|
||||
@ -351,7 +351,7 @@ pub fn parse(args: &[String]) -> Flags {
|
||||
|
||||
// fn usage()
|
||||
let usage = |exit_code: i32, opts: &Options, verbose: bool, subcommand_help: &str| -> ! {
|
||||
let config = Config::parse(&["build".to_string()]);
|
||||
let config = Config::parse(&["setup".to_string()]);
|
||||
let build = Build::new(config);
|
||||
let paths = Builder::get_help(&build, subcommand);
|
||||
|
||||
@ -621,7 +621,7 @@ pub fn parse(args: &[String]) -> Flags {
|
||||
}
|
||||
Kind::Setup => {
|
||||
let profile = if paths.len() > 1 {
|
||||
println!("\nat most one profile can be passed to setup\n");
|
||||
eprintln!("\nerror: At most one profile can be passed to setup\n");
|
||||
usage(1, &opts, verbose, &subcommand_help)
|
||||
} else if let Some(path) = paths.pop() {
|
||||
let profile_string = t!(path.into_os_string().into_string().map_err(
|
||||
|
@ -713,10 +713,6 @@ pub fn build(&mut self) {
|
||||
return clean::clean(self, all);
|
||||
}
|
||||
|
||||
if let Subcommand::Setup { profile } = &self.config.cmd {
|
||||
return setup::setup(&self.config, *profile);
|
||||
}
|
||||
|
||||
// Download rustfmt early so that it can be used in rust-analyzer configs.
|
||||
let _ = &builder::Builder::new(&self).initial_rustfmt();
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
use crate::builder::{Builder, RunConfig, ShouldRun, Step};
|
||||
use crate::Config;
|
||||
use crate::{t, VERSION};
|
||||
use std::env::consts::EXE_SUFFIX;
|
||||
@ -9,7 +10,7 @@
|
||||
use std::str::FromStr;
|
||||
use std::{fmt, fs, io};
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
|
||||
pub enum Profile {
|
||||
Compiler,
|
||||
Codegen,
|
||||
@ -48,6 +49,16 @@ pub fn all_for_help(indent: &str) -> String {
|
||||
}
|
||||
out
|
||||
}
|
||||
|
||||
pub fn as_str(&self) -> &'static str {
|
||||
match self {
|
||||
Profile::Compiler => "compiler",
|
||||
Profile::Codegen => "codegen",
|
||||
Profile::Library => "library",
|
||||
Profile::Tools => "tools",
|
||||
Profile::User => "user",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for Profile {
|
||||
@ -69,24 +80,58 @@ fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
|
||||
impl fmt::Display for Profile {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Profile::Compiler => write!(f, "compiler"),
|
||||
Profile::Codegen => write!(f, "codegen"),
|
||||
Profile::Library => write!(f, "library"),
|
||||
Profile::User => write!(f, "user"),
|
||||
Profile::Tools => write!(f, "tools"),
|
||||
}
|
||||
f.write_str(self.as_str())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn setup(config: &Config, profile: Option<Profile>) {
|
||||
let profile = profile.unwrap_or_else(|| t!(interactive_path()));
|
||||
impl Step for Profile {
|
||||
type Output = ();
|
||||
const DEFAULT: bool = true;
|
||||
|
||||
fn should_run(mut run: ShouldRun<'_>) -> ShouldRun<'_> {
|
||||
for choice in Profile::all() {
|
||||
run = run.alias(choice.as_str());
|
||||
}
|
||||
run
|
||||
}
|
||||
|
||||
fn make_run(run: RunConfig<'_>) {
|
||||
// for Profile, `run.paths` will have 1 and only 1 element
|
||||
// this is because we only accept at most 1 path from user input.
|
||||
// If user calls `x.py setup` without arguments, the interactive TUI
|
||||
// will guide user to provide one.
|
||||
let profile = if run.paths.len() > 1 {
|
||||
// HACK: `builder` runs this step with all paths if no path was passed.
|
||||
t!(interactive_path())
|
||||
} else {
|
||||
run.paths
|
||||
.first()
|
||||
.unwrap()
|
||||
.assert_single_path()
|
||||
.path
|
||||
.as_path()
|
||||
.as_os_str()
|
||||
.to_str()
|
||||
.unwrap()
|
||||
.parse()
|
||||
.unwrap()
|
||||
};
|
||||
|
||||
run.builder.ensure(profile);
|
||||
}
|
||||
|
||||
fn run(self, builder: &Builder<'_>) {
|
||||
setup(&builder.build.config, self)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn setup(config: &Config, profile: Profile) {
|
||||
let stage_path =
|
||||
["build", config.build.rustc_target_arg(), "stage1"].join(&MAIN_SEPARATOR.to_string());
|
||||
|
||||
if !rustup_installed() && profile != Profile::User {
|
||||
eprintln!("`rustup` is not installed; cannot link `stage1` toolchain");
|
||||
} else if stage_dir_exists(&stage_path[..]) {
|
||||
} else if stage_dir_exists(&stage_path[..]) && !config.dry_run() {
|
||||
attempt_toolchain_link(&stage_path[..]);
|
||||
}
|
||||
|
||||
@ -104,7 +149,9 @@ pub fn setup(config: &Config, profile: Option<Profile>) {
|
||||
Profile::User => &["dist", "build"],
|
||||
};
|
||||
|
||||
if !config.dry_run() {
|
||||
t!(install_git_hook_maybe(&config));
|
||||
}
|
||||
|
||||
println!();
|
||||
|
||||
@ -144,6 +191,7 @@ fn setup_config_toml(path: &PathBuf, profile: Profile, config: &Config) {
|
||||
changelog-seen = {}\n",
|
||||
profile, VERSION
|
||||
);
|
||||
|
||||
t!(fs::write(path, settings));
|
||||
|
||||
let include_path = profile.include_path(&config.src);
|
||||
|
Loading…
Reference in New Issue
Block a user