Skip to content

Commit 20b927a

Browse files
authored
Rollup merge of rust-lang#96003 - aswild:pr/bootstrap-subcommands-cleanup, r=jyn514
bootstrap: consolidate subcommand parsing and matching There's several places where the x.py command names are matched as strings, leading to some inconsistencies and opportunities for cleanup. * Add Format, Clean, and Setup variants to builder::Kind. * Use Kind to parse the x.py subcommand name (including aliases) * Match on the subcommand Kind rather than strings when handling options and help text. * Several subcommands don't display any paths when run with `-h -v` even though the help text indicates that they should. Fix this and refactor so that manually keeping matches in sync isn't necessary. Fixes rust-lang#95937
2 parents 818baab + 870cb8e commit 20b927a

File tree

2 files changed

+85
-103
lines changed

2 files changed

+85
-103
lines changed

src/bootstrap/builder.rs

Lines changed: 35 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::cell::{Cell, RefCell};
33
use std::collections::BTreeSet;
44
use std::env;
55
use std::ffi::OsStr;
6-
use std::fmt::Debug;
6+
use std::fmt::{Debug, Write};
77
use std::fs;
88
use std::hash::Hash;
99
use std::ops::Deref;
@@ -125,7 +125,8 @@ impl TaskPath {
125125
if found_kind.is_empty() {
126126
panic!("empty kind in task path {}", path.display());
127127
}
128-
kind = Some(Kind::parse(found_kind));
128+
kind = Kind::parse(found_kind);
129+
assert!(kind.is_some());
129130
path = Path::new(found_prefix).join(components.as_path());
130131
}
131132
}
@@ -429,43 +430,53 @@ pub enum Kind {
429430
Check,
430431
Clippy,
431432
Fix,
433+
Format,
432434
Test,
433435
Bench,
434-
Dist,
435436
Doc,
437+
Clean,
438+
Dist,
436439
Install,
437440
Run,
441+
Setup,
438442
}
439443

440444
impl Kind {
441-
fn parse(string: &str) -> Kind {
442-
match string {
443-
"build" => Kind::Build,
444-
"check" => Kind::Check,
445+
pub fn parse(string: &str) -> Option<Kind> {
446+
// these strings, including the one-letter aliases, must match the x.py help text
447+
Some(match string {
448+
"build" | "b" => Kind::Build,
449+
"check" | "c" => Kind::Check,
445450
"clippy" => Kind::Clippy,
446451
"fix" => Kind::Fix,
447-
"test" => Kind::Test,
452+
"fmt" => Kind::Format,
453+
"test" | "t" => Kind::Test,
448454
"bench" => Kind::Bench,
455+
"doc" | "d" => Kind::Doc,
456+
"clean" => Kind::Clean,
449457
"dist" => Kind::Dist,
450-
"doc" => Kind::Doc,
451458
"install" => Kind::Install,
452-
"run" => Kind::Run,
453-
other => panic!("unknown kind: {}", other),
454-
}
459+
"run" | "r" => Kind::Run,
460+
"setup" => Kind::Setup,
461+
_ => return None,
462+
})
455463
}
456464

457-
fn as_str(&self) -> &'static str {
465+
pub fn as_str(&self) -> &'static str {
458466
match self {
459467
Kind::Build => "build",
460468
Kind::Check => "check",
461469
Kind::Clippy => "clippy",
462470
Kind::Fix => "fix",
471+
Kind::Format => "fmt",
463472
Kind::Test => "test",
464473
Kind::Bench => "bench",
465-
Kind::Dist => "dist",
466474
Kind::Doc => "doc",
475+
Kind::Clean => "clean",
476+
Kind::Dist => "dist",
467477
Kind::Install => "install",
468478
Kind::Run => "run",
479+
Kind::Setup => "setup",
469480
}
470481
}
471482
}
@@ -509,7 +520,7 @@ impl<'a> Builder<'a> {
509520
native::Lld,
510521
native::CrtBeginEnd
511522
),
512-
Kind::Check | Kind::Clippy { .. } | Kind::Fix => describe!(
523+
Kind::Check => describe!(
513524
check::Std,
514525
check::Rustc,
515526
check::Rustdoc,
@@ -639,32 +650,29 @@ impl<'a> Builder<'a> {
639650
install::Rustc
640651
),
641652
Kind::Run => describe!(run::ExpandYamlAnchors, run::BuildManifest, run::BumpStage0),
653+
// These commands either don't use paths, or they're special-cased in Build::build()
654+
Kind::Clean | Kind::Clippy | Kind::Fix | Kind::Format | Kind::Setup => vec![],
642655
}
643656
}
644657

645-
pub fn get_help(build: &Build, subcommand: &str) -> Option<String> {
646-
let kind = match subcommand {
647-
"build" | "b" => Kind::Build,
648-
"doc" | "d" => Kind::Doc,
649-
"test" | "t" => Kind::Test,
650-
"bench" => Kind::Bench,
651-
"dist" => Kind::Dist,
652-
"install" => Kind::Install,
653-
_ => return None,
654-
};
658+
pub fn get_help(build: &Build, kind: Kind) -> Option<String> {
659+
let step_descriptions = Builder::get_step_descriptions(kind);
660+
if step_descriptions.is_empty() {
661+
return None;
662+
}
655663

656664
let builder = Self::new_internal(build, kind, vec![]);
657665
let builder = &builder;
658666
// The "build" kind here is just a placeholder, it will be replaced with something else in
659667
// the following statement.
660668
let mut should_run = ShouldRun::new(builder, Kind::Build);
661-
for desc in Builder::get_step_descriptions(builder.kind) {
669+
for desc in step_descriptions {
662670
should_run.kind = desc.kind;
663671
should_run = (desc.should_run)(should_run);
664672
}
665673
let mut help = String::from("Available paths:\n");
666674
let mut add_path = |path: &Path| {
667-
help.push_str(&format!(" ./x.py {} {}\n", subcommand, path.display()));
675+
t!(write!(help, " ./x.py {} {}\n", kind.as_str(), path.display()));
668676
};
669677
for pathset in should_run.paths {
670678
match pathset {

0 commit comments

Comments
 (0)