@@ -144,6 +144,12 @@ enum RustupSubcmd {
144144 #[ command( subcommand) ]
145145 subcmd : ToolchainSubcmd ,
146146 } ,
147+
148+ /// Modify a toolchain's supported targets
149+ Target {
150+ #[ command( subcommand) ]
151+ subcmd : TargetSubcmd ,
152+ } ,
147153}
148154
149155#[ derive( Debug , Subcommand ) ]
@@ -249,6 +255,45 @@ struct UninstallOpts {
249255 toolchain : Vec < ResolvableToolchainName > ,
250256}
251257
258+ #[ derive( Debug , Subcommand ) ]
259+ #[ command( arg_required_else_help = true , subcommand_required = true ) ]
260+ enum TargetSubcmd {
261+ /// List installed and available targets
262+ List {
263+ #[ arg(
264+ long,
265+ help = OFFICIAL_TOOLCHAIN_ARG_HELP ,
266+ ) ]
267+ toolchain : Option < PartialToolchainDesc > ,
268+
269+ /// List only installed targets
270+ #[ arg( long) ]
271+ installed : bool ,
272+ } ,
273+
274+ /// Add a target to a Rust toolchain
275+ #[ command( alias = "install" ) ]
276+ Add {
277+ /// List of targets to install; "all" installs all available targets
278+ #[ arg( required = true , num_args = 1 ..) ]
279+ target : Vec < String > ,
280+
281+ #[ arg( long, help = OFFICIAL_TOOLCHAIN_ARG_HELP ) ]
282+ toolchain : Option < PartialToolchainDesc > ,
283+ } ,
284+
285+ /// Remove a target from a Rust toolchain
286+ #[ command( alias = "uninstall" ) ]
287+ Remove {
288+ /// List of targets to uninstall
289+ #[ arg( required = true , num_args = 1 ..) ]
290+ target : Vec < String > ,
291+
292+ #[ arg( long, help = OFFICIAL_TOOLCHAIN_ARG_HELP ) ]
293+ toolchain : Option < PartialToolchainDesc > ,
294+ } ,
295+ }
296+
252297impl Rustup {
253298 fn dispatch ( self , cfg : & mut Cfg ) -> Result < utils:: ExitCode > {
254299 match self . subcmd {
@@ -285,6 +330,14 @@ impl Rustup {
285330 } ,
286331 RustupSubcmd :: Check => check_updates ( cfg) ,
287332 RustupSubcmd :: Default { toolchain } => default_ ( cfg, toolchain) ,
333+ RustupSubcmd :: Target { subcmd } => match subcmd {
334+ TargetSubcmd :: List {
335+ toolchain,
336+ installed,
337+ } => handle_epipe ( target_list ( cfg, toolchain, installed) ) ,
338+ TargetSubcmd :: Add { target, toolchain } => target_add ( cfg, target, toolchain) ,
339+ TargetSubcmd :: Remove { target, toolchain } => target_remove ( cfg, target, toolchain) ,
340+ } ,
288341 }
289342 }
290343}
@@ -362,18 +415,10 @@ pub fn main() -> Result<utils::ExitCode> {
362415 Some ( s) => match s {
363416 ( "dump-testament" , _) => common:: dump_testament ( ) ?,
364417 (
365- "show" | "update" | "install" | "uninstall" | "toolchain" | "check" | "default" ,
418+ "show" | "update" | "install" | "uninstall" | "toolchain" | "check" | "default"
419+ | "target" ,
366420 _,
367421 ) => Rustup :: from_arg_matches ( & matches) ?. dispatch ( cfg) ?,
368- ( "target" , c) => match c. subcommand ( ) {
369- Some ( s) => match s {
370- ( "list" , m) => handle_epipe ( target_list ( cfg, m) ) ?,
371- ( "add" , m) => target_add ( cfg, m) ?,
372- ( "remove" , m) => target_remove ( cfg, m) ?,
373- _ => unreachable ! ( ) ,
374- } ,
375- None => unreachable ! ( ) ,
376- } ,
377422 ( "component" , c) => match c. subcommand ( ) {
378423 Some ( s) => match s {
379424 ( "list" , m) => handle_epipe ( component_list ( cfg, m) ) ?,
@@ -470,63 +515,6 @@ pub(crate) fn cli() -> Command {
470515 . about ( "Dump information about the build" )
471516 . hide ( true ) , // Not for users, only CI
472517 )
473- . subcommand (
474- Command :: new ( "target" )
475- . about ( "Modify a toolchain's supported targets" )
476- . subcommand_required ( true )
477- . arg_required_else_help ( true )
478- . subcommand (
479- Command :: new ( "list" )
480- . about ( "List installed and available targets" )
481- . arg (
482- Arg :: new ( "toolchain" )
483- . help ( OFFICIAL_TOOLCHAIN_ARG_HELP )
484- . long ( "toolchain" )
485- . value_parser ( partial_toolchain_desc_parser)
486- . num_args ( 1 ) ,
487- )
488- . arg (
489- Arg :: new ( "installed" )
490- . long ( "installed" )
491- . help ( "List only installed targets" )
492- . action ( ArgAction :: SetTrue ) ,
493- ) ,
494- )
495- . subcommand (
496- Command :: new ( "add" )
497- . about ( "Add a target to a Rust toolchain" )
498- . alias ( "install" )
499- . arg ( Arg :: new ( "target" ) . required ( true ) . num_args ( 1 ..) . help (
500- "List of targets to install; \
501- \" all\" installs all available targets",
502- ) )
503- . arg (
504- Arg :: new ( "toolchain" )
505- . help ( OFFICIAL_TOOLCHAIN_ARG_HELP )
506- . long ( "toolchain" )
507- . num_args ( 1 )
508- . value_parser ( partial_toolchain_desc_parser) ,
509- ) ,
510- )
511- . subcommand (
512- Command :: new ( "remove" )
513- . about ( "Remove a target from a Rust toolchain" )
514- . alias ( "uninstall" )
515- . arg (
516- Arg :: new ( "target" )
517- . help ( "List of targets to uninstall" )
518- . required ( true )
519- . num_args ( 1 ..) ,
520- )
521- . arg (
522- Arg :: new ( "toolchain" )
523- . help ( OFFICIAL_TOOLCHAIN_ARG_HELP )
524- . long ( "toolchain" )
525- . num_args ( 1 )
526- . value_parser ( partial_toolchain_desc_parser) ,
527- ) ,
528- ) ,
529- )
530518 . subcommand (
531519 Command :: new ( "component" )
532520 . about ( "Modify a toolchain's installed components" )
@@ -1176,27 +1164,30 @@ fn show_rustup_home(cfg: &Cfg) -> Result<utils::ExitCode> {
11761164 Ok ( utils:: ExitCode ( 0 ) )
11771165}
11781166
1179- fn target_list ( cfg : & Cfg , m : & ArgMatches ) -> Result < utils:: ExitCode > {
1180- let toolchain = explicit_desc_or_dir_toolchain ( cfg, m) ?;
1167+ fn target_list (
1168+ cfg : & Cfg ,
1169+ toolchain : Option < PartialToolchainDesc > ,
1170+ installed_only : bool ,
1171+ ) -> Result < utils:: ExitCode > {
1172+ let toolchain = explicit_desc_or_dir_toolchain ( cfg, toolchain) ?;
11811173 // downcasting required because the toolchain files can name any toolchain
11821174 let distributable = ( & toolchain) . try_into ( ) ?;
1183- common:: list_targets ( distributable, m . get_flag ( "installed" ) )
1175+ common:: list_targets ( distributable, installed_only )
11841176}
11851177
1186- fn target_add ( cfg : & Cfg , m : & ArgMatches ) -> Result < utils:: ExitCode > {
1187- let toolchain = explicit_desc_or_dir_toolchain ( cfg, m) ?;
1178+ fn target_add (
1179+ cfg : & Cfg ,
1180+ mut targets : Vec < String > ,
1181+ toolchain : Option < PartialToolchainDesc > ,
1182+ ) -> Result < utils:: ExitCode > {
1183+ let toolchain = explicit_desc_or_dir_toolchain ( cfg, toolchain) ?;
11881184 // XXX: long term move this error to cli ? the normal .into doesn't work
11891185 // because Result here is the wrong sort and expression type ascription
11901186 // isn't a feature yet.
11911187 // list_components *and* add_component would both be inappropriate for
11921188 // custom toolchains.
11931189 let distributable = DistributableToolchain :: try_from ( & toolchain) ?;
11941190 let components = distributable. components ( ) ?;
1195- let mut targets: Vec < _ > = m
1196- . get_many :: < String > ( "target" )
1197- . unwrap ( )
1198- . map ( ToOwned :: to_owned)
1199- . collect ( ) ;
12001191
12011192 if targets. contains ( & "all" . to_string ( ) ) {
12021193 if targets. len ( ) != 1 {
@@ -1234,12 +1225,16 @@ fn target_add(cfg: &Cfg, m: &ArgMatches) -> Result<utils::ExitCode> {
12341225 Ok ( utils:: ExitCode ( 0 ) )
12351226}
12361227
1237- fn target_remove ( cfg : & Cfg , m : & ArgMatches ) -> Result < utils:: ExitCode > {
1238- let toolchain = explicit_desc_or_dir_toolchain ( cfg, m) ?;
1228+ fn target_remove (
1229+ cfg : & Cfg ,
1230+ targets : Vec < String > ,
1231+ toolchain : Option < PartialToolchainDesc > ,
1232+ ) -> Result < utils:: ExitCode > {
1233+ let toolchain = explicit_desc_or_dir_toolchain ( cfg, toolchain) ?;
12391234 let distributable = DistributableToolchain :: try_from ( & toolchain) ?;
12401235
1241- for target in m . get_many :: < String > ( "target" ) . unwrap ( ) {
1242- let target = TargetTriple :: new ( target) ;
1236+ for target in targets {
1237+ let target = TargetTriple :: new ( & target) ;
12431238 let default_target = cfg. get_default_host_triple ( ) ?;
12441239 if target == default_target {
12451240 warn ! ( "after removing the default host target, proc-macros and build scripts might no longer build" ) ;
@@ -1266,15 +1261,15 @@ fn target_remove(cfg: &Cfg, m: &ArgMatches) -> Result<utils::ExitCode> {
12661261}
12671262
12681263fn component_list ( cfg : & Cfg , m : & ArgMatches ) -> Result < utils:: ExitCode > {
1269- let toolchain = explicit_desc_or_dir_toolchain ( cfg, m) ?;
1264+ let toolchain = explicit_desc_or_dir_toolchain_old ( cfg, m) ?;
12701265 // downcasting required because the toolchain files can name any toolchain
12711266 let distributable = ( & toolchain) . try_into ( ) ?;
12721267 common:: list_components ( distributable, m. get_flag ( "installed" ) ) ?;
12731268 Ok ( utils:: ExitCode ( 0 ) )
12741269}
12751270
12761271fn component_add ( cfg : & Cfg , m : & ArgMatches ) -> Result < utils:: ExitCode > {
1277- let toolchain = explicit_desc_or_dir_toolchain ( cfg, m) ?;
1272+ let toolchain = explicit_desc_or_dir_toolchain_old ( cfg, m) ?;
12781273 let distributable = DistributableToolchain :: try_from ( & toolchain) ?;
12791274 let target = get_target ( m, & distributable) ;
12801275
@@ -1294,7 +1289,7 @@ fn get_target(m: &ArgMatches, distributable: &DistributableToolchain<'_>) -> Opt
12941289}
12951290
12961291fn component_remove ( cfg : & Cfg , m : & ArgMatches ) -> Result < utils:: ExitCode > {
1297- let toolchain = explicit_desc_or_dir_toolchain ( cfg, m) ?;
1292+ let toolchain = explicit_desc_or_dir_toolchain_old ( cfg, m) ?;
12981293 let distributable = DistributableToolchain :: try_from ( & toolchain) ?;
12991294 let target = get_target ( m, & distributable) ;
13001295
@@ -1308,13 +1303,21 @@ fn component_remove(cfg: &Cfg, m: &ArgMatches) -> Result<utils::ExitCode> {
13081303
13091304// Make *sure* only to use this for a subcommand whose "toolchain" argument
13101305// has .value_parser(partial_toolchain_desc_parser), or it will panic.
1311- fn explicit_desc_or_dir_toolchain < ' a > ( cfg : & ' a Cfg , m : & ArgMatches ) -> Result < Toolchain < ' a > > {
1306+ // FIXME: Delete this.
1307+ fn explicit_desc_or_dir_toolchain_old < ' a > ( cfg : & ' a Cfg , m : & ArgMatches ) -> Result < Toolchain < ' a > > {
13121308 let toolchain = m
13131309 . get_one :: < PartialToolchainDesc > ( "toolchain" )
13141310 . map ( Into :: into) ;
13151311 explicit_or_dir_toolchain2 ( cfg, toolchain)
13161312}
13171313
1314+ fn explicit_desc_or_dir_toolchain (
1315+ cfg : & Cfg ,
1316+ toolchain : Option < PartialToolchainDesc > ,
1317+ ) -> Result < Toolchain < ' _ > > {
1318+ explicit_or_dir_toolchain2 ( cfg, toolchain. map ( |it| ( & it) . into ( ) ) )
1319+ }
1320+
13181321fn explicit_or_dir_toolchain2 (
13191322 cfg : & Cfg ,
13201323 toolchain : Option < ResolvableToolchainName > ,
@@ -1458,7 +1461,7 @@ const DOCS_DATA: &[(&str, &str, &str)] = &[
14581461] ;
14591462
14601463fn doc ( cfg : & Cfg , m : & ArgMatches ) -> Result < utils:: ExitCode > {
1461- let toolchain = explicit_desc_or_dir_toolchain ( cfg, m) ?;
1464+ let toolchain = explicit_desc_or_dir_toolchain_old ( cfg, m) ?;
14621465
14631466 if let Ok ( distributable) = DistributableToolchain :: try_from ( & toolchain) {
14641467 if let [ _] = distributable
@@ -1522,7 +1525,7 @@ fn man(cfg: &Cfg, m: &ArgMatches) -> Result<utils::ExitCode> {
15221525
15231526 let command = m. get_one :: < String > ( "command" ) . unwrap ( ) ;
15241527
1525- let toolchain = explicit_desc_or_dir_toolchain ( cfg, m) ?;
1528+ let toolchain = explicit_desc_or_dir_toolchain_old ( cfg, m) ?;
15261529 let mut path = toolchain. path ( ) . to_path_buf ( ) ;
15271530 path. push ( "share" ) ;
15281531 path. push ( "man" ) ;
0 commit comments