Skip to content

Commit

Permalink
refactor(cli): rewrite rustup (run|which|dump-testament) with `clap…
Browse files Browse the repository at this point in the history
…-derive`
  • Loading branch information
rami3l committed May 12, 2024
1 parent 675e1a3 commit 7c171af
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 87 deletions.
110 changes: 50 additions & 60 deletions src/cli/rustup_mode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,7 @@ use crate::{
toolchain::{
distributable::DistributableToolchain,
names::{
partial_toolchain_desc_parser, resolvable_local_toolchainame_parser,
resolvable_toolchainame_parser, CustomToolchainName, LocalToolchainName,
partial_toolchain_desc_parser, CustomToolchainName, LocalToolchainName,
MaybeResolvableToolchainName, ResolvableLocalToolchainName, ResolvableToolchainName,
ToolchainName,
},
Expand Down Expand Up @@ -95,6 +94,10 @@ enum RustupSubcmd {
opts: UninstallOpts,
},

/// Dump information about the build
#[command(hide = true)]
DumpTestament,

/// Show the active and installed toolchains or profiles
#[command(after_help = SHOW_HELP)]
Show {
Expand Down Expand Up @@ -162,6 +165,28 @@ enum RustupSubcmd {
#[command(subcommand)]
subcmd: OverrideSubcmd,
},

/// Run a command with an environment configured for a given toolchain
#[command(after_help = RUN_HELP, trailing_var_arg = true)]
Run {
#[arg(help = RESOLVABLE_LOCAL_TOOLCHAIN_ARG_HELP)]
toolchain: ResolvableLocalToolchainName,

#[arg(required = true, num_args = 1.., use_value_delimiter = false)]
command: Vec<String>,

/// Install the requested toolchain if needed
#[arg(long)]
install: bool,
},

/// Display which binary will be run for a given command
Which {
command: String,

#[arg(long, help = RESOLVABLE_TOOLCHAIN_ARG_HELP)]
toolchain: Option<ResolvableToolchainName>,
},
}

#[derive(Debug, Subcommand)]
Expand Down Expand Up @@ -381,6 +406,7 @@ enum OverrideSubcmd {
impl Rustup {
fn dispatch(self, cfg: &mut Cfg) -> Result<utils::ExitCode> {
match self.subcmd {
RustupSubcmd::DumpTestament => common::dump_testament(),
RustupSubcmd::Install { opts } => update(cfg, opts),
RustupSubcmd::Uninstall { opts } => toolchain_remove(cfg, opts),
RustupSubcmd::Show { verbose, subcmd } => match subcmd {
Expand Down Expand Up @@ -447,6 +473,12 @@ impl Rustup {
override_remove(cfg, path.as_deref(), nonexistent)
}
},
RustupSubcmd::Run {
toolchain,
command,
install,
} => run(cfg, toolchain, command, install),
RustupSubcmd::Which { command, toolchain } => which(cfg, &command, toolchain),
}
}
}
Expand Down Expand Up @@ -522,14 +554,11 @@ pub fn main() -> Result<utils::ExitCode> {

Ok(match matches.subcommand() {
Some(s) => match s {
("dump-testament", _) => common::dump_testament()?,
(
"show" | "update" | "install" | "uninstall" | "toolchain" | "check" | "default"
| "target" | "component" | "override",
"dump-testament" | "show" | "update" | "install" | "uninstall" | "toolchain"
| "check" | "default" | "target" | "component" | "override" | "run" | "which",
_,
) => Rustup::from_arg_matches(&matches)?.dispatch(cfg)?,
("run", m) => run(cfg, m)?,
("which", m) => which(cfg, m)?,
("doc", m) => doc(cfg, m)?,
#[cfg(not(windows))]
("man", m) => man(cfg, m)?,
Expand Down Expand Up @@ -601,48 +630,6 @@ pub(crate) fn cli() -> Command {
}
}),
)
.subcommand(
Command::new("dump-testament")
.about("Dump information about the build")
.hide(true), // Not for users, only CI
)
.subcommand(
Command::new("run")
.about("Run a command with an environment configured for a given toolchain")
.after_help(RUN_HELP)
.trailing_var_arg(true)
.arg(
Arg::new("toolchain")
.help(RESOLVABLE_LOCAL_TOOLCHAIN_ARG_HELP)
.required(true)
.num_args(1)
.value_parser(resolvable_local_toolchainame_parser),
)
.arg(
Arg::new("command")
.required(true)
.num_args(1..)
.use_value_delimiter(false),
)
.arg(
Arg::new("install")
.help("Install the requested toolchain if needed")
.long("install")
.action(ArgAction::SetTrue),
),
)
.subcommand(
Command::new("which")
.about("Display which binary will be run for a given command")
.arg(Arg::new("command").required(true))
.arg(
Arg::new("toolchain")
.help(RESOLVABLE_TOOLCHAIN_ARG_HELP)
.long("toolchain")
.num_args(1)
.value_parser(resolvable_toolchainame_parser),
),
)
.subcommand(
Command::new("doc")
.alias("docs")
Expand Down Expand Up @@ -965,22 +952,25 @@ fn update(cfg: &mut Cfg, opts: UpdateOpts) -> Result<utils::ExitCode> {
Ok(utils::ExitCode(0))
}

fn run(cfg: &Cfg, m: &ArgMatches) -> Result<utils::ExitCode> {
let toolchain = m
.get_one::<ResolvableLocalToolchainName>("toolchain")
.unwrap();
let args = m.get_many::<String>("command").unwrap();
let args: Vec<_> = args.collect();
fn run(
cfg: &Cfg,
toolchain: ResolvableLocalToolchainName,
command: Vec<String>,
install: bool,
) -> Result<utils::ExitCode> {
let toolchain = toolchain.resolve(&cfg.get_default_host_triple()?)?;
let cmd = cfg.create_command_for_toolchain(&toolchain, m.get_flag("install"), args[0])?;
let cmd = cfg.create_command_for_toolchain(&toolchain, install, &command[0])?;

let code = command::run_command_for_dir(cmd, args[0], &args[1..])?;
let code = command::run_command_for_dir(cmd, &command[0], &command[1..])?;
Ok(code)
}

fn which(cfg: &Cfg, m: &ArgMatches) -> Result<utils::ExitCode> {
let binary = m.get_one::<String>("command").unwrap();
let binary_path = if let Some(toolchain) = m.get_one::<ResolvableToolchainName>("toolchain") {
fn which(
cfg: &Cfg,
binary: &str,
toolchain: Option<ResolvableToolchainName>,
) -> Result<utils::ExitCode> {
let binary_path = if let Some(toolchain) = toolchain {
let desc = toolchain.resolve(&cfg.get_default_host_triple()?)?;
Toolchain::new(cfg, desc.into())?.binary_file(binary)
} else {
Expand Down
15 changes: 0 additions & 15 deletions src/toolchain/names.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,15 +185,6 @@ impl Display for ResolvableToolchainName {
}
}

/// Thunk to avoid errors like
/// = note: `fn(&'2 str) -> Result<CustomToolchainName, <CustomToolchainName as TryFrom<&'2 str>>::Error> {<CustomToolchainName as TryFrom<&'2 str>>::try_from}` must implement `FnOnce<(&'1 str,)>`, for any lifetime `'1`...
/// = note: ...but it actually implements `FnOnce<(&'2 str,)>`, for some specific lifetime `'2`
pub(crate) fn resolvable_toolchainame_parser(
value: &str,
) -> Result<ResolvableToolchainName, InvalidName> {
ResolvableToolchainName::try_from(value)
}

/// A toolchain name from user input. MaybeToolchainName accepts 'none' or a
/// custom or resolvable official name. Possibly this should be an Option with a
/// local trait for our needs.
Expand Down Expand Up @@ -366,12 +357,6 @@ impl Display for ResolvableLocalToolchainName {
}
}

pub(crate) fn resolvable_local_toolchainame_parser(
value: &str,
) -> Result<ResolvableLocalToolchainName, InvalidName> {
ResolvableLocalToolchainName::try_from(value)
}

/// LocalToolchainName can be used in calls to Cfg that alter configuration,
/// like setting overrides, or that depend on configuration, like calculating
/// the toolchain directory. It is not used to model the RUSTUP_TOOLCHAIN
Expand Down
4 changes: 2 additions & 2 deletions tests/suite/cli-ui/rustup/rustup_help_cmd_stdout.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ The Rust toolchain installer
Usage: rustup[EXE] [OPTIONS] [+toolchain] [COMMAND]
Commands:
run Run a command with an environment configured for a given toolchain
which Display which binary will be run for a given command
doc Open the documentation for the current toolchain
...
self Modify the rustup installation
Expand All @@ -24,6 +22,8 @@ Commands:
target Modify a toolchain's supported targets
component Modify a toolchain's installed components
override Modify toolchain overrides for directories
run Run a command with an environment configured for a given toolchain
which Display which binary will be run for a given command
help Print this message or the help of the given subcommand(s)
Arguments:
Expand Down
4 changes: 2 additions & 2 deletions tests/suite/cli-ui/rustup/rustup_help_flag_stdout.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ The Rust toolchain installer
Usage: rustup[EXE] [OPTIONS] [+toolchain] [COMMAND]
Commands:
run Run a command with an environment configured for a given toolchain
which Display which binary will be run for a given command
doc Open the documentation for the current toolchain
...
self Modify the rustup installation
Expand All @@ -24,6 +22,8 @@ Commands:
target Modify a toolchain's supported targets
component Modify a toolchain's installed components
override Modify toolchain overrides for directories
run Run a command with an environment configured for a given toolchain
which Display which binary will be run for a given command
help Print this message or the help of the given subcommand(s)
Arguments:
Expand Down
4 changes: 2 additions & 2 deletions tests/suite/cli-ui/rustup/rustup_only_options_stdout.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ The Rust toolchain installer
Usage: rustup[EXE] [OPTIONS] [+toolchain] [COMMAND]
Commands:
run Run a command with an environment configured for a given toolchain
which Display which binary will be run for a given command
doc Open the documentation for the current toolchain
...
self Modify the rustup installation
Expand All @@ -24,6 +22,8 @@ Commands:
target Modify a toolchain's supported targets
component Modify a toolchain's installed components
override Modify toolchain overrides for directories
run Run a command with an environment configured for a given toolchain
which Display which binary will be run for a given command
help Print this message or the help of the given subcommand(s)
Arguments:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ stdout = """
...
Run a command with an environment configured for a given toolchain
Usage: rustup[EXE] run [OPTIONS] <toolchain> <command>...
Usage: rustup[EXE] run [OPTIONS] <TOOLCHAIN> <COMMAND>...
Arguments:
<toolchain> Toolchain name, such as 'stable', 'nightly', '1.8.0', or a custom toolchain name, or
<TOOLCHAIN> Toolchain name, such as 'stable', 'nightly', '1.8.0', or a custom toolchain name, or
an absolute path. For more information see `rustup help toolchain`
<command>...
<COMMAND>...
Options:
--install Install the requested toolchain if needed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ stdout = """
...
Display which binary will be run for a given command
Usage: rustup[EXE] which [OPTIONS] <command>
Usage: rustup[EXE] which [OPTIONS] <COMMAND>
Arguments:
<command>
<COMMAND>
Options:
--toolchain <toolchain> Toolchain name, such as 'stable', 'nightly', '1.8.0', or a custom
--toolchain <TOOLCHAIN> Toolchain name, such as 'stable', 'nightly', '1.8.0', or a custom
toolchain name. For more information see `rustup help toolchain`
-h, --help Print help
"""

0 comments on commit 7c171af

Please sign in to comment.