Skip to content

Commit 870cb8e

Browse files
committed
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 #95937
1 parent d9b3ff7 commit 870cb8e

File tree

2 files changed

+85
-103
lines changed

2 files changed

+85
-103
lines changed

src/bootstrap/builder.rs

+35-27
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
}
@@ -406,43 +407,53 @@ pub enum Kind {
406407
Check,
407408
Clippy,
408409
Fix,
410+
Format,
409411
Test,
410412
Bench,
411-
Dist,
412413
Doc,
414+
Clean,
415+
Dist,
413416
Install,
414417
Run,
418+
Setup,
415419
}
416420

417421
impl Kind {
418-
fn parse(string: &str) -> Kind {
419-
match string {
420-
"build" => Kind::Build,
421-
"check" => Kind::Check,
422+
pub fn parse(string: &str) -> Option<Kind> {
423+
// these strings, including the one-letter aliases, must match the x.py help text
424+
Some(match string {
425+
"build" | "b" => Kind::Build,
426+
"check" | "c" => Kind::Check,
422427
"clippy" => Kind::Clippy,
423428
"fix" => Kind::Fix,
424-
"test" => Kind::Test,
429+
"fmt" => Kind::Format,
430+
"test" | "t" => Kind::Test,
425431
"bench" => Kind::Bench,
432+
"doc" | "d" => Kind::Doc,
433+
"clean" => Kind::Clean,
426434
"dist" => Kind::Dist,
427-
"doc" => Kind::Doc,
428435
"install" => Kind::Install,
429-
"run" => Kind::Run,
430-
other => panic!("unknown kind: {}", other),
431-
}
436+
"run" | "r" => Kind::Run,
437+
"setup" => Kind::Setup,
438+
_ => return None,
439+
})
432440
}
433441

434-
fn as_str(&self) -> &'static str {
442+
pub fn as_str(&self) -> &'static str {
435443
match self {
436444
Kind::Build => "build",
437445
Kind::Check => "check",
438446
Kind::Clippy => "clippy",
439447
Kind::Fix => "fix",
448+
Kind::Format => "fmt",
440449
Kind::Test => "test",
441450
Kind::Bench => "bench",
442-
Kind::Dist => "dist",
443451
Kind::Doc => "doc",
452+
Kind::Clean => "clean",
453+
Kind::Dist => "dist",
444454
Kind::Install => "install",
445455
Kind::Run => "run",
456+
Kind::Setup => "setup",
446457
}
447458
}
448459
}
@@ -486,7 +497,7 @@ impl<'a> Builder<'a> {
486497
native::Lld,
487498
native::CrtBeginEnd
488499
),
489-
Kind::Check | Kind::Clippy { .. } | Kind::Fix => describe!(
500+
Kind::Check => describe!(
490501
check::Std,
491502
check::Rustc,
492503
check::Rustdoc,
@@ -616,32 +627,29 @@ impl<'a> Builder<'a> {
616627
install::Rustc
617628
),
618629
Kind::Run => describe!(run::ExpandYamlAnchors, run::BuildManifest, run::BumpStage0),
630+
// These commands either don't use paths, or they're special-cased in Build::build()
631+
Kind::Clean | Kind::Clippy | Kind::Fix | Kind::Format | Kind::Setup => vec![],
619632
}
620633
}
621634

622-
pub fn get_help(build: &Build, subcommand: &str) -> Option<String> {
623-
let kind = match subcommand {
624-
"build" | "b" => Kind::Build,
625-
"doc" | "d" => Kind::Doc,
626-
"test" | "t" => Kind::Test,
627-
"bench" => Kind::Bench,
628-
"dist" => Kind::Dist,
629-
"install" => Kind::Install,
630-
_ => return None,
631-
};
635+
pub fn get_help(build: &Build, kind: Kind) -> Option<String> {
636+
let step_descriptions = Builder::get_step_descriptions(kind);
637+
if step_descriptions.is_empty() {
638+
return None;
639+
}
632640

633641
let builder = Self::new_internal(build, kind, vec![]);
634642
let builder = &builder;
635643
// The "build" kind here is just a placeholder, it will be replaced with something else in
636644
// the following statement.
637645
let mut should_run = ShouldRun::new(builder, Kind::Build);
638-
for desc in Builder::get_step_descriptions(builder.kind) {
646+
for desc in step_descriptions {
639647
should_run.kind = desc.kind;
640648
should_run = (desc.should_run)(should_run);
641649
}
642650
let mut help = String::from("Available paths:\n");
643651
let mut add_path = |path: &Path| {
644-
help.push_str(&format!(" ./x.py {} {}\n", subcommand, path.display()));
652+
t!(write!(help, " ./x.py {} {}\n", kind.as_str(), path.display()));
645653
};
646654
for pathset in should_run.paths {
647655
match pathset {

0 commit comments

Comments
 (0)