Skip to content

Commit 72ca385

Browse files
committed
refactor(cli): rewrite rustup (self|set) with clap-derive
1 parent e250bd5 commit 72ca385

10 files changed

+104
-123
lines changed

src/cli/rustup_mode.rs

Lines changed: 82 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use std::str::FromStr;
66
use anyhow::{anyhow, Error, Result};
77
use clap::{
88
builder::{PossibleValue, PossibleValuesParser},
9-
Arg, ArgAction, ArgMatches, Args, Command, FromArgMatches as _, Parser, Subcommand, ValueEnum,
9+
Arg, ArgAction, Args, Command, FromArgMatches as _, Parser, Subcommand, ValueEnum,
1010
};
1111
use clap_complete::Shell;
1212
use itertools::Itertools;
@@ -215,6 +215,18 @@ enum RustupSubcmd {
215215
toolchain: Option<PartialToolchainDesc>,
216216
},
217217

218+
/// Modify the rustup installation
219+
Self_ {
220+
#[command(subcommand)]
221+
subcmd: SelfSubcmd,
222+
},
223+
224+
/// Alter rustup settings
225+
Set {
226+
#[command(subcommand)]
227+
subcmd: SetSubcmd,
228+
},
229+
218230
/// Generate tab-completion scripts for your shell
219231
#[command(after_help = COMPLETIONS_HELP, arg_required_else_help = true)]
220232
Completions {
@@ -439,6 +451,51 @@ enum OverrideSubcmd {
439451
},
440452
}
441453

454+
#[derive(Debug, Subcommand)]
455+
#[command(
456+
name = "self",
457+
arg_required_else_help = true,
458+
subcommand_required = true
459+
)]
460+
enum SelfSubcmd {
461+
/// Download and install updates to rustup
462+
Update,
463+
464+
/// Uninstall rustup
465+
Uninstall {
466+
#[arg(short = 'y')]
467+
no_prompt: bool,
468+
},
469+
470+
/// Upgrade the internal data format
471+
UpgradeData,
472+
}
473+
474+
#[derive(Debug, Subcommand)]
475+
#[command(arg_required_else_help = true, subcommand_required = true)]
476+
enum SetSubcmd {
477+
/// The triple used to identify toolchains when not specified
478+
DefaultHost { host_triple: String },
479+
480+
/// The default components installed with a toolchain
481+
Profile {
482+
#[arg(
483+
default_value = Profile::default_name(),
484+
value_parser = PossibleValuesParser::new(Profile::names()),
485+
)]
486+
profile_name: String,
487+
},
488+
489+
/// The rustup auto self update mode
490+
AutoSelfUpdate {
491+
#[arg(
492+
default_value = SelfUpdateMode::default_mode(),
493+
value_parser = PossibleValuesParser::new(SelfUpdateMode::modes()),
494+
)]
495+
auto_self_update_mode: String,
496+
},
497+
}
498+
442499
impl Rustup {
443500
fn dispatch(self, cfg: &mut Cfg) -> Result<utils::ExitCode> {
444501
match self.subcmd {
@@ -523,6 +580,20 @@ impl Rustup {
523580
} => doc(cfg, path, toolchain, topic.as_deref(), &page),
524581
#[cfg(not(windows))]
525582
RustupSubcmd::Man { command, toolchain } => man(cfg, &command, toolchain),
583+
RustupSubcmd::Self_ { subcmd } => match subcmd {
584+
SelfSubcmd::Update => self_update::update(cfg),
585+
SelfSubcmd::Uninstall { no_prompt } => self_update::uninstall(no_prompt),
586+
SelfSubcmd::UpgradeData => upgrade_data(cfg),
587+
},
588+
RustupSubcmd::Set { subcmd } => match subcmd {
589+
SetSubcmd::DefaultHost { host_triple } => {
590+
set_default_host_triple(cfg, &host_triple)
591+
}
592+
SetSubcmd::Profile { profile_name } => set_profile(cfg, &profile_name),
593+
SetSubcmd::AutoSelfUpdate {
594+
auto_self_update_mode,
595+
} => set_auto_self_update(cfg, &auto_self_update_mode),
596+
},
526597
RustupSubcmd::Completions { shell, command } => {
527598
output_completion_script(shell, command)
528599
}
@@ -593,39 +664,10 @@ pub fn main() -> Result<utils::ExitCode> {
593664
cfg.set_toolchain_override(t);
594665
}
595666

596-
if maybe_upgrade_data(cfg, &matches)? {
597-
return Ok(utils::ExitCode(0));
598-
}
599-
600667
cfg.check_metadata_version()?;
601668

602669
Ok(match matches.subcommand() {
603-
Some(s) => match s {
604-
(
605-
"dump-testament" | "show" | "update" | "install" | "uninstall" | "toolchain"
606-
| "check" | "default" | "target" | "component" | "override" | "run" | "which"
607-
| "doc" | "man" | "completions",
608-
_,
609-
) => Rustup::from_arg_matches(&matches)?.dispatch(cfg)?,
610-
("self", c) => match c.subcommand() {
611-
Some(s) => match s {
612-
("update", _) => self_update::update(cfg)?,
613-
("uninstall", m) => self_uninstall(m)?,
614-
_ => unreachable!(),
615-
},
616-
None => unreachable!(),
617-
},
618-
("set", c) => match c.subcommand() {
619-
Some(s) => match s {
620-
("default-host", m) => set_default_host_triple(cfg, m)?,
621-
("profile", m) => set_profile(cfg, m)?,
622-
("auto-self-update", m) => set_auto_self_update(cfg, m)?,
623-
_ => unreachable!(),
624-
},
625-
None => unreachable!(),
626-
},
627-
_ => unreachable!(),
628-
},
670+
Some(_) => Rustup::from_arg_matches(&matches)?.dispatch(cfg)?,
629671
None => {
630672
eprintln!("{}", cli().render_long_help());
631673
utils::ExitCode(1)
@@ -662,54 +704,7 @@ pub(crate) fn cli() -> Command {
662704
Err(Error::raw(ErrorKind::InvalidSubcommand, format!("\"{s}\" is not a valid subcommand, so it was interpreted as a toolchain name, but it is also invalid. {TOOLCHAIN_OVERRIDE_ERROR}")))
663705
}
664706
}),
665-
)
666-
.subcommand(
667-
Command::new("self")
668-
.about("Modify the rustup installation")
669-
.subcommand_required(true)
670-
.arg_required_else_help(true)
671-
.subcommand(Command::new("update").about("Download and install updates to rustup"))
672-
.subcommand(
673-
Command::new("uninstall")
674-
.about("Uninstall rustup.")
675-
.arg(Arg::new("no-prompt").short('y').action(ArgAction::SetTrue)),
676-
)
677-
.subcommand(
678-
Command::new("upgrade-data").about("Upgrade the internal data format."),
679-
),
680-
)
681-
.subcommand(
682-
Command::new("set")
683-
.about("Alter rustup settings")
684-
.subcommand_required(true)
685-
.arg_required_else_help(true)
686-
.subcommand(
687-
Command::new("default-host")
688-
.about("The triple used to identify toolchains when not specified")
689-
.arg(Arg::new("host_triple").required(true)),
690-
)
691-
.subcommand(
692-
Command::new("profile")
693-
.about("The default components installed with a toolchain")
694-
.arg(
695-
Arg::new("profile-name")
696-
.required(true)
697-
.value_parser(PossibleValuesParser::new(Profile::names()))
698-
.default_value(Profile::default_name()),
699-
),
700-
)
701-
.subcommand(
702-
Command::new("auto-self-update")
703-
.about("The rustup auto self update mode")
704-
.arg(
705-
Arg::new("auto-self-update-mode")
706-
.required(true)
707-
.value_parser(PossibleValuesParser::new(SelfUpdateMode::modes()))
708-
.default_value(SelfUpdateMode::default_mode()),
709-
),
710-
),
711707
);
712-
713708
RustupSubcmd::augment_subcommands(app)
714709
}
715710

@@ -721,17 +716,9 @@ fn verbose_arg(help: &'static str) -> Arg {
721716
.action(ArgAction::SetTrue)
722717
}
723718

724-
fn maybe_upgrade_data(cfg: &Cfg, m: &ArgMatches) -> Result<bool> {
725-
match m.subcommand() {
726-
Some(("self", c)) => match c.subcommand() {
727-
Some(("upgrade-data", _)) => {
728-
cfg.upgrade_data()?;
729-
Ok(true)
730-
}
731-
_ => Ok(false),
732-
},
733-
_ => Ok(false),
734-
}
719+
fn upgrade_data(cfg: &Cfg) -> Result<utils::ExitCode> {
720+
cfg.upgrade_data()?;
721+
Ok(utils::ExitCode(0))
735722
}
736723

737724
fn default_(cfg: &Cfg, toolchain: Option<MaybeResolvableToolchainName>) -> Result<utils::ExitCode> {
@@ -1541,23 +1528,17 @@ fn man(
15411528
Ok(utils::ExitCode(0))
15421529
}
15431530

1544-
fn self_uninstall(m: &ArgMatches) -> Result<utils::ExitCode> {
1545-
let no_prompt = m.get_flag("no-prompt");
1546-
1547-
self_update::uninstall(no_prompt)
1548-
}
1549-
1550-
fn set_default_host_triple(cfg: &Cfg, m: &ArgMatches) -> Result<utils::ExitCode> {
1551-
cfg.set_default_host_triple(m.get_one::<String>("host_triple").unwrap())?;
1531+
fn set_default_host_triple(cfg: &Cfg, host_triple: &str) -> Result<utils::ExitCode> {
1532+
cfg.set_default_host_triple(host_triple)?;
15521533
Ok(utils::ExitCode(0))
15531534
}
15541535

1555-
fn set_profile(cfg: &mut Cfg, m: &ArgMatches) -> Result<utils::ExitCode> {
1556-
cfg.set_profile(m.get_one::<String>("profile-name").unwrap())?;
1536+
fn set_profile(cfg: &mut Cfg, profile: &str) -> Result<utils::ExitCode> {
1537+
cfg.set_profile(profile)?;
15571538
Ok(utils::ExitCode(0))
15581539
}
15591540

1560-
fn set_auto_self_update(cfg: &mut Cfg, m: &ArgMatches) -> Result<utils::ExitCode> {
1541+
fn set_auto_self_update(cfg: &mut Cfg, auto_self_update_mode: &str) -> Result<utils::ExitCode> {
15611542
if self_update::NEVER_SELF_UPDATE {
15621543
let mut args = crate::process().args_os();
15631544
let arg0 = args.next().map(PathBuf::from);
@@ -1567,7 +1548,7 @@ fn set_auto_self_update(cfg: &mut Cfg, m: &ArgMatches) -> Result<utils::ExitCode
15671548
.ok_or(CLIError::NoExeName)?;
15681549
warn!("{} is built with the no-self-update feature: setting auto-self-update will not have any effect.",arg0);
15691550
}
1570-
cfg.set_auto_self_update(m.get_one::<String>("auto-self-update-mode").unwrap())?;
1551+
cfg.set_auto_self_update(auto_self_update_mode)?;
15711552
Ok(utils::ExitCode(0))
15721553
}
15731554

tests/suite/cli-ui/rustup/rustup_help_cmd_stdout.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@ The Rust toolchain installer
99
Usage: rustup[EXE] [OPTIONS] [+toolchain] [COMMAND]
1010
1111
Commands:
12-
self Modify the rustup installation
13-
set Alter rustup settings
1412
show Show the active and installed toolchains or profiles
1513
update Update Rust toolchains and rustup
1614
check Check for updates to Rust toolchains and rustup
@@ -23,6 +21,8 @@ Commands:
2321
which Display which binary will be run for a given command
2422
doc Open the documentation for the current toolchain
2523
...
24+
self Modify the rustup installation
25+
set Alter rustup settings
2626
completions Generate tab-completion scripts for your shell
2727
help Print this message or the help of the given subcommand(s)
2828

tests/suite/cli-ui/rustup/rustup_help_flag_stdout.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@ The Rust toolchain installer
99
Usage: rustup[EXE] [OPTIONS] [+toolchain] [COMMAND]
1010
1111
Commands:
12-
self Modify the rustup installation
13-
set Alter rustup settings
1412
show Show the active and installed toolchains or profiles
1513
update Update Rust toolchains and rustup
1614
check Check for updates to Rust toolchains and rustup
@@ -23,6 +21,8 @@ Commands:
2321
which Display which binary will be run for a given command
2422
doc Open the documentation for the current toolchain
2523
...
24+
self Modify the rustup installation
25+
set Alter rustup settings
2626
completions Generate tab-completion scripts for your shell
2727
help Print this message or the help of the given subcommand(s)
2828

tests/suite/cli-ui/rustup/rustup_only_options_stdout.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@ The Rust toolchain installer
99
Usage: rustup[EXE] [OPTIONS] [+toolchain] [COMMAND]
1010
1111
Commands:
12-
self Modify the rustup installation
13-
set Alter rustup settings
1412
show Show the active and installed toolchains or profiles
1513
update Update Rust toolchains and rustup
1614
check Check for updates to Rust toolchains and rustup
@@ -23,6 +21,8 @@ Commands:
2321
which Display which binary will be run for a given command
2422
doc Open the documentation for the current toolchain
2523
...
24+
self Modify the rustup installation
25+
set Alter rustup settings
2626
completions Generate tab-completion scripts for your shell
2727
help Print this message or the help of the given subcommand(s)
2828

tests/suite/cli-ui/rustup/rustup_self_cmd_help_flag_stdout.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
bin.name = "rustup"
2-
args = ["self","--help"]
2+
args = ["self", "--help"]
33
stdout = """
44
...
55
Modify the rustup installation
@@ -8,8 +8,8 @@ Usage: rustup[EXE] self <COMMAND>
88
99
Commands:
1010
update Download and install updates to rustup
11-
uninstall Uninstall rustup.
12-
upgrade-data Upgrade the internal data format.
11+
uninstall Uninstall rustup
12+
upgrade-data Upgrade the internal data format
1313
help Print this message or the help of the given subcommand(s)
1414
1515
Options:

tests/suite/cli-ui/rustup/rustup_self_cmd_uninstall_cmd_help_flag_stdout.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
bin.name = "rustup"
2-
args = ["self","uninstall","--help"]
2+
args = ["self", "uninstall", "--help"]
33
stdout = """
44
...
5-
Uninstall rustup.
5+
Uninstall rustup
66
77
Usage: rustup[EXE] self uninstall [OPTIONS]
88

tests/suite/cli-ui/rustup/rustup_self_cmd_upgrade-data _cmd_help_flag_stdout.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
bin.name = "rustup"
2-
args = ["self","upgrade-data","--help"]
2+
args = ["self", "upgrade-data", "--help"]
33
stdout = """
44
...
5-
Upgrade the internal data format.
5+
Upgrade the internal data format
66
77
Usage: rustup[EXE] self upgrade-data
88

tests/suite/cli-ui/rustup/rustup_set_cmd_auto-self-update_cmd_help_flag_stdout.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
bin.name = "rustup"
2-
args = ["set","auto-self-update","--help"]
2+
args = ["set", "auto-self-update", "--help"]
33
stdout = """
44
...
55
The rustup auto self update mode
66
7-
Usage: rustup[EXE] set auto-self-update <auto-self-update-mode>
7+
Usage: rustup[EXE] set auto-self-update [AUTO_SELF_UPDATE_MODE]
88
99
Arguments:
10-
<auto-self-update-mode> [default: enable] [possible values: enable, disable, check-only]
10+
[AUTO_SELF_UPDATE_MODE] [default: enable] [possible values: enable, disable, check-only]
1111
1212
Options:
1313
-h, --help Print help

tests/suite/cli-ui/rustup/rustup_set_cmd_default-host_cmd_help_flag_stdout.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
bin.name = "rustup"
2-
args = ["set","default-host","--help"]
2+
args = ["set", "default-host", "--help"]
33
stdout = """
44
...
55
The triple used to identify toolchains when not specified
66
7-
Usage: rustup[EXE] set default-host <host_triple>
7+
Usage: rustup[EXE] set default-host <HOST_TRIPLE>
88
99
Arguments:
10-
<host_triple>
10+
<HOST_TRIPLE>
1111
1212
Options:
1313
-h, --help Print help

0 commit comments

Comments
 (0)