@@ -6,7 +6,8 @@ use std::str::FromStr;
6
6
use anyhow:: { anyhow, Error , Result } ;
7
7
use clap:: {
8
8
builder:: { EnumValueParser , PossibleValue , PossibleValuesParser } ,
9
- Arg , ArgAction , ArgGroup , ArgMatches , Command , ValueEnum ,
9
+ Arg , ArgAction , ArgGroup , ArgMatches , Command , FromArgMatches as _, Parser , Subcommand ,
10
+ ValueEnum ,
10
11
} ;
11
12
use clap_complete:: Shell ;
12
13
use itertools:: Itertools ;
86
87
callee ( cfg, matches)
87
88
}
88
89
90
+ #[ derive( Debug , Parser ) ]
91
+ #[ command(
92
+ name = "rustup" ,
93
+ bin_name = "rustup[EXE]" ,
94
+ version = common:: version( ) ,
95
+ ) ]
96
+ struct Rustup {
97
+ #[ command( subcommand) ]
98
+ subcmd : RustupSubcmd ,
99
+ }
100
+
101
+ #[ derive( Debug , Subcommand ) ]
102
+ enum RustupSubcmd {
103
+ /// Show the active and installed toolchains or profiles
104
+ #[ command( after_help = SHOW_HELP ) ]
105
+ Show {
106
+ /// Enable verbose output with rustc information for all installed toolchains
107
+ #[ arg( short, long) ]
108
+ verbose : bool ,
109
+
110
+ #[ command( subcommand) ]
111
+ subcmd : Option < ShowSubcmd > ,
112
+ } ,
113
+ }
114
+
115
+ #[ derive( Debug , Subcommand ) ]
116
+ enum ShowSubcmd {
117
+ /// Show the active toolchain
118
+ #[ command( after_help = SHOW_ACTIVE_TOOLCHAIN_HELP ) ]
119
+ ActiveToolchain {
120
+ /// Enable verbose output with rustc information
121
+ #[ arg( short, long) ]
122
+ verbose : bool ,
123
+ } ,
124
+
125
+ /// Display the computed value of RUSTUP_HOME
126
+ Home ,
127
+
128
+ /// Show the default profile used for the `rustup install` command
129
+ Profile ,
130
+ }
131
+
132
+ impl Rustup {
133
+ fn dispatch ( self , cfg : & mut Cfg ) -> Result < utils:: ExitCode > {
134
+ match self . subcmd {
135
+ RustupSubcmd :: Show { verbose, subcmd } => match subcmd {
136
+ None => handle_epipe ( show ( cfg, verbose) ) ,
137
+ Some ( ShowSubcmd :: ActiveToolchain { verbose } ) => {
138
+ handle_epipe ( show_active_toolchain ( cfg, verbose) )
139
+ }
140
+ Some ( ShowSubcmd :: Home ) => handle_epipe ( show_rustup_home ( cfg) ) ,
141
+ Some ( ShowSubcmd :: Profile ) => handle_epipe ( show_profile ( cfg) ) ,
142
+ } ,
143
+ }
144
+ }
145
+ }
146
+
89
147
#[ cfg_attr( feature = "otel" , tracing:: instrument( fields( args = format!( "{:?}" , process( ) . args_os( ) . collect:: <Vec <_>>( ) ) ) ) ) ]
90
148
pub fn main ( ) -> Result < utils:: ExitCode > {
91
149
self_update:: cleanup_self_updater ( ) ?;
@@ -158,15 +216,7 @@ pub fn main() -> Result<utils::ExitCode> {
158
216
Ok ( match matches. subcommand ( ) {
159
217
Some ( s) => match s {
160
218
( "dump-testament" , _) => common:: dump_testament ( ) ?,
161
- ( "show" , c) => match c. subcommand ( ) {
162
- Some ( s) => match s {
163
- ( "active-toolchain" , m) => handle_epipe ( show_active_toolchain ( cfg, m) ) ?,
164
- ( "home" , _) => handle_epipe ( show_rustup_home ( cfg) ) ?,
165
- ( "profile" , _) => handle_epipe ( show_profile ( cfg) ) ?,
166
- _ => handle_epipe ( show ( cfg, c) ) ?,
167
- } ,
168
- None => handle_epipe ( show ( cfg, c) ) ?,
169
- } ,
219
+ ( "show" , _) => Rustup :: from_arg_matches ( & matches) ?. dispatch ( cfg) ?,
170
220
( "install" , m) => deprecated ( "toolchain install" , cfg, m, update) ?,
171
221
( "update" , m) => update ( cfg, m) ?,
172
222
( "check" , _) => check_updates ( cfg) ?,
@@ -287,106 +337,6 @@ pub(crate) fn cli() -> Command {
287
337
. about ( "Dump information about the build" )
288
338
. hide ( true ) , // Not for users, only CI
289
339
)
290
- . subcommand (
291
- Command :: new ( "show" )
292
- . about ( "Show the active and installed toolchains or profiles" )
293
- . after_help ( SHOW_HELP )
294
- . arg (
295
- verbose_arg ( "Enable verbose output with rustc information for all installed toolchains" ) ,
296
- )
297
- . subcommand (
298
- Command :: new ( "active-toolchain" )
299
- . about ( "Show the active toolchain" )
300
- . after_help ( SHOW_ACTIVE_TOOLCHAIN_HELP )
301
- . arg (
302
- verbose_arg ( "Enable verbose output with rustc information" ) ,
303
- ) ,
304
- )
305
- . subcommand (
306
- Command :: new ( "home" )
307
- . about ( "Display the computed value of RUSTUP_HOME" ) ,
308
- )
309
- . subcommand ( Command :: new ( "profile" ) . about ( "Show the default profile used for the `rustup install` command" ) )
310
- )
311
- . subcommand (
312
- Command :: new ( "install" )
313
- . about ( "Update Rust toolchains" )
314
- . after_help ( INSTALL_HELP )
315
- . hide ( true ) // synonym for 'toolchain install'
316
- . arg (
317
- Arg :: new ( "toolchain" )
318
- . help ( OFFICIAL_TOOLCHAIN_ARG_HELP )
319
- . required ( true )
320
- . value_parser ( partial_toolchain_desc_parser)
321
- . num_args ( 1 ..)
322
- )
323
- . arg (
324
- Arg :: new ( "profile" )
325
- . long ( "profile" )
326
- . value_parser ( PossibleValuesParser :: new ( Profile :: names ( ) ) )
327
- . num_args ( 1 ) ,
328
- )
329
- . arg (
330
- Arg :: new ( "no-self-update" )
331
- . help ( "Don't perform self-update when running the `rustup install` command" )
332
- . long ( "no-self-update" )
333
- . action ( ArgAction :: SetTrue )
334
- )
335
- . arg (
336
- Arg :: new ( "force" )
337
- . help ( "Force an update, even if some components are missing" )
338
- . long ( "force" )
339
- . action ( ArgAction :: SetTrue )
340
- ) . arg (
341
- Arg :: new ( "force-non-host" )
342
- . help ( "Install toolchains that require an emulator. See https://github.com/rust-lang/rustup/wiki/Non-host-toolchains" )
343
- . long ( "force-non-host" )
344
- . action ( ArgAction :: SetTrue )
345
- ) ,
346
- )
347
- . subcommand (
348
- Command :: new ( "uninstall" )
349
- . about ( "Uninstall Rust toolchains" )
350
- . hide ( true ) // synonym for 'toolchain uninstall'
351
- . arg (
352
- Arg :: new ( "toolchain" )
353
- . help ( RESOLVABLE_TOOLCHAIN_ARG_HELP )
354
- . required ( true )
355
- . value_parser ( resolvable_toolchainame_parser)
356
- . num_args ( 1 ..)
357
- ) ,
358
- )
359
- . subcommand (
360
- Command :: new ( "update" )
361
- . about ( "Update Rust toolchains and rustup" )
362
- . aliases ( [ "upgrade" , "up" ] )
363
- . after_help ( UPDATE_HELP )
364
- . arg (
365
- Arg :: new ( "toolchain" )
366
- . help ( OFFICIAL_TOOLCHAIN_ARG_HELP )
367
- . required ( false )
368
- . value_parser ( partial_toolchain_desc_parser)
369
- . num_args ( 1 ..)
370
- )
371
- . arg (
372
- Arg :: new ( "no-self-update" )
373
- . help ( "Don't perform self update when running the `rustup update` command" )
374
- . long ( "no-self-update" )
375
- . action ( ArgAction :: SetTrue )
376
- )
377
- . arg (
378
- Arg :: new ( "force" )
379
- . help ( "Force an update, even if some components are missing" )
380
- . long ( "force" )
381
- . action ( ArgAction :: SetTrue )
382
- )
383
- . arg (
384
- Arg :: new ( "force-non-host" )
385
- . help ( "Install toolchains that require an emulator. See https://github.com/rust-lang/rustup/wiki/Non-host-toolchains" )
386
- . long ( "force-non-host" )
387
- . action ( ArgAction :: SetTrue )
388
- ) ,
389
- )
390
340
. subcommand ( Command :: new ( "check" ) . about ( "Check for updates to Rust toolchains and rustup" ) )
391
341
. subcommand (
392
342
Command :: new ( "default" )
@@ -804,20 +754,21 @@ pub(crate) fn cli() -> Command {
804
754
. default_value ( SelfUpdateMode :: default_mode ( ) ) ,
805
755
) ,
806
756
) ,
757
+ )
758
+ . subcommand (
759
+ Command :: new ( "completions" )
760
+ . about ( "Generate tab-completion scripts for your shell" )
761
+ . after_help ( COMPLETIONS_HELP )
762
+ . arg_required_else_help ( true )
763
+ . arg ( Arg :: new ( "shell" ) . value_parser ( EnumValueParser :: < Shell > :: new ( ) ) )
764
+ . arg (
765
+ Arg :: new ( "command" )
766
+ . value_parser ( EnumValueParser :: < CompletionCommand > :: new ( ) )
767
+ . default_missing_value ( "rustup" ) ,
768
+ ) ,
807
769
) ;
808
770
809
- app. subcommand (
810
- Command :: new ( "completions" )
811
- . about ( "Generate tab-completion scripts for your shell" )
812
- . after_help ( COMPLETIONS_HELP )
813
- . arg_required_else_help ( true )
814
- . arg ( Arg :: new ( "shell" ) . value_parser ( EnumValueParser :: < Shell > :: new ( ) ) )
815
- . arg (
816
- Arg :: new ( "command" )
817
- . value_parser ( EnumValueParser :: < CompletionCommand > :: new ( ) )
818
- . default_missing_value ( "rustup" ) ,
819
- ) ,
820
- )
771
+ RustupSubcmd :: augment_subcommands ( app)
821
772
}
822
773
823
774
fn verbose_arg ( help : & ' static str ) -> Arg {
@@ -1061,11 +1012,9 @@ fn which(cfg: &Cfg, m: &ArgMatches) -> Result<utils::ExitCode> {
1061
1012
}
1062
1013
1063
1014
#[ cfg_attr( feature = "otel" , tracing:: instrument( skip_all) ) ]
1064
- fn show ( cfg : & Cfg , m : & ArgMatches ) -> Result < utils:: ExitCode > {
1015
+ fn show ( cfg : & Cfg , verbose : bool ) -> Result < utils:: ExitCode > {
1065
1016
common:: warn_if_host_is_emulated ( ) ;
1066
1017
1067
- let verbose = m. get_flag ( "verbose" ) ;
1068
-
1069
1018
// Print host triple
1070
1019
{
1071
1020
let mut t = process ( ) . stdout ( ) . terminal ( ) ;
@@ -1201,8 +1150,7 @@ fn show(cfg: &Cfg, m: &ArgMatches) -> Result<utils::ExitCode> {
1201
1150
}
1202
1151
1203
1152
#[ cfg_attr( feature = "otel" , tracing:: instrument( skip_all) ) ]
1204
- fn show_active_toolchain ( cfg : & Cfg , m : & ArgMatches ) -> Result < utils:: ExitCode > {
1205
- let verbose = m. get_flag ( "verbose" ) ;
1153
+ fn show_active_toolchain ( cfg : & Cfg , verbose : bool ) -> Result < utils:: ExitCode > {
1206
1154
let cwd = utils:: current_dir ( ) ?;
1207
1155
match cfg. find_active_toolchain ( & cwd) ? {
1208
1156
Some ( ( toolchain_name, reason) ) => {
0 commit comments