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