@@ -91,16 +91,19 @@ Run with 'cargo -Z [FLAG] [SUBCOMMAND]'"
91
91
return Ok ( ( ) ) ;
92
92
}
93
93
94
- let args = expand_aliases ( config, args) ?;
95
- let ( cmd, subcommand_args) = match args. subcommand ( ) {
94
+ // Global args need to be extracted before expanding aliases because the
95
+ // clap code for extracting a subcommand discards global options
96
+ // (appearing before the subcommand).
97
+ let ( expanded_args, global_args) = expand_aliases ( config, args) ?;
98
+ let ( cmd, subcommand_args) = match expanded_args. subcommand ( ) {
96
99
( cmd, Some ( args) ) => ( cmd, args) ,
97
100
_ => {
98
101
// No subcommand provided.
99
102
cli ( ) . print_help ( ) ?;
100
103
return Ok ( ( ) ) ;
101
104
}
102
105
} ;
103
- config_configure ( config, & args , subcommand_args) ?;
106
+ config_configure ( config, & expanded_args , subcommand_args, global_args ) ?;
104
107
super :: init_git_transports ( config) ;
105
108
106
109
execute_subcommand ( config, cmd, subcommand_args)
@@ -128,7 +131,7 @@ pub fn get_version_string(is_verbose: bool) -> String {
128
131
fn expand_aliases (
129
132
config : & mut Config ,
130
133
args : ArgMatches < ' static > ,
131
- ) -> Result < ArgMatches < ' static > , CliError > {
134
+ ) -> Result < ( ArgMatches < ' static > , GlobalArgs ) , CliError > {
132
135
if let ( cmd, Some ( args) ) = args. subcommand ( ) {
133
136
match (
134
137
commands:: builtin_exec ( cmd) ,
@@ -147,41 +150,60 @@ fn expand_aliases(
147
150
. unwrap_or_default ( )
148
151
. map ( |s| s. to_string ( ) ) ,
149
152
) ;
150
- let args = cli ( )
153
+ // new_args strips out everything before the subcommand, so
154
+ // capture those global options now.
155
+ // Note that an alias to an external command will not receive
156
+ // these arguments. That may be confusing, but such is life.
157
+ let global_args = GlobalArgs :: new ( & args) ;
158
+ let new_args = cli ( )
151
159
. setting ( AppSettings :: NoBinaryName )
152
160
. get_matches_from_safe ( alias) ?;
153
- return expand_aliases ( config, args) ;
161
+ let ( expanded_args, _) = expand_aliases ( config, new_args) ?;
162
+ return Ok ( ( expanded_args, global_args) ) ;
154
163
}
155
164
( _, None ) => { }
156
165
}
157
166
} ;
158
167
159
- Ok ( args)
168
+ Ok ( ( args, GlobalArgs :: default ( ) ) )
160
169
}
161
170
162
171
fn config_configure (
163
172
config : & mut Config ,
164
173
args : & ArgMatches < ' _ > ,
165
174
subcommand_args : & ArgMatches < ' _ > ,
175
+ global_args : GlobalArgs ,
166
176
) -> CliResult {
167
177
let arg_target_dir = & subcommand_args. value_of_path ( "target-dir" , config) ;
168
- let config_args: Vec < & str > = args. values_of ( "config" ) . unwrap_or_default ( ) . collect ( ) ;
169
- let quiet = if args. is_present ( "quiet" ) || subcommand_args. is_present ( "quiet" ) {
170
- Some ( true )
171
- } else {
172
- None
173
- } ;
178
+ let verbose = global_args. verbose + args. occurrences_of ( "verbose" ) as u32 ;
179
+ // quiet is unusual because it is redefined in some subcommands in order
180
+ // to provide custom help text.
181
+ let quiet =
182
+ args. is_present ( "quiet" ) || subcommand_args. is_present ( "quiet" ) || global_args. quiet ;
183
+ let global_color = global_args. color ; // Extract so it can take reference.
184
+ let color = args
185
+ . value_of ( "color" )
186
+ . or_else ( || global_color. as_ref ( ) . map ( |s| s. as_ref ( ) ) ) ;
187
+ let frozen = args. is_present ( "frozen" ) || global_args. frozen ;
188
+ let locked = args. is_present ( "locked" ) || global_args. locked ;
189
+ let offline = args. is_present ( "offline" ) || global_args. offline ;
190
+ let mut unstable_flags = global_args. unstable_flags ;
191
+ if let Some ( values) = args. values_of ( "unstable-features" ) {
192
+ unstable_flags. extend ( values. map ( |s| s. to_string ( ) ) ) ;
193
+ }
194
+ let mut config_args = global_args. config_args ;
195
+ if let Some ( values) = args. values_of ( "config" ) {
196
+ config_args. extend ( values. map ( |s| s. to_string ( ) ) ) ;
197
+ }
174
198
config. configure (
175
- args . occurrences_of ( " verbose" ) as u32 ,
199
+ verbose,
176
200
quiet,
177
- args . value_of ( " color" ) ,
178
- args . is_present ( " frozen" ) ,
179
- args . is_present ( " locked" ) ,
180
- args . is_present ( " offline" ) ,
201
+ color,
202
+ frozen,
203
+ locked,
204
+ offline,
181
205
arg_target_dir,
182
- & args
183
- . values_of_lossy ( "unstable-features" )
184
- . unwrap_or_default ( ) ,
206
+ & unstable_flags,
185
207
& config_args,
186
208
) ?;
187
209
Ok ( ( ) )
@@ -201,6 +223,39 @@ fn execute_subcommand(
201
223
super :: execute_external_subcommand ( config, cmd, & ext_args)
202
224
}
203
225
226
+ #[ derive( Default ) ]
227
+ struct GlobalArgs {
228
+ verbose : u32 ,
229
+ quiet : bool ,
230
+ color : Option < String > ,
231
+ frozen : bool ,
232
+ locked : bool ,
233
+ offline : bool ,
234
+ unstable_flags : Vec < String > ,
235
+ config_args : Vec < String > ,
236
+ }
237
+
238
+ impl GlobalArgs {
239
+ fn new ( args : & ArgMatches < ' _ > ) -> GlobalArgs {
240
+ GlobalArgs {
241
+ verbose : args. occurrences_of ( "verbose" ) as u32 ,
242
+ quiet : args. is_present ( "quiet" ) ,
243
+ color : args. value_of ( "color" ) . map ( |s| s. to_string ( ) ) ,
244
+ frozen : args. is_present ( "frozen" ) ,
245
+ locked : args. is_present ( "locked" ) ,
246
+ offline : args. is_present ( "offline" ) ,
247
+ unstable_flags : args
248
+ . values_of_lossy ( "unstable-features" )
249
+ . unwrap_or_default ( ) ,
250
+ config_args : args
251
+ . values_of ( "config" )
252
+ . unwrap_or_default ( )
253
+ . map ( |s| s. to_string ( ) )
254
+ . collect ( ) ,
255
+ }
256
+ }
257
+ }
258
+
204
259
fn cli ( ) -> App {
205
260
App :: new ( "cargo" )
206
261
. settings ( & [
0 commit comments