@@ -120,9 +120,7 @@ fn parse_cli(raw_args: Vec<OsString>) -> Result<cli::Cli, clap::Error> {
120120 Ok ( cli) => Ok ( cli) ,
121121 Err ( err) => {
122122 if should_default_to_build ( & err, & raw_args) {
123- let mut fallback_args = raw_args. clone ( ) ;
124- let insert_at = index_after_global_flags ( & fallback_args) ;
125- fallback_args. insert ( insert_at, OsString :: from ( "build" ) ) ;
123+ let fallback_args = build_default_args ( & raw_args) ;
126124
127125 match cli:: Cli :: try_parse_from ( & fallback_args) {
128126 Ok ( cli) => Ok ( cli) ,
@@ -151,18 +149,6 @@ fn should_default_to_build(err: &clap::Error, args: &[OsString]) -> bool {
151149 }
152150}
153151
154- fn index_after_global_flags ( args : & [ OsString ] ) -> usize {
155- let mut idx = 1 ;
156- while let Some ( arg) = args. get ( idx) {
157- if is_global_flag ( arg) {
158- idx += 1 ;
159- } else {
160- break ;
161- }
162- }
163- idx. min ( args. len ( ) )
164- }
165-
166152fn is_global_flag ( arg : & OsString ) -> bool {
167153 matches ! (
168154 arg. to_str( ) ,
@@ -198,9 +184,44 @@ fn is_known_subcommand(arg: &OsString) -> bool {
198184 } )
199185}
200186
187+ fn build_default_args ( raw_args : & [ OsString ] ) -> Vec < OsString > {
188+ let mut result = Vec :: with_capacity ( raw_args. len ( ) + 1 ) ;
189+ if raw_args. is_empty ( ) {
190+ return vec ! [ OsString :: from( "build" ) ] ;
191+ }
192+
193+ let mut globals = Vec :: new ( ) ;
194+ let mut others = Vec :: new ( ) ;
195+ let mut saw_double_dash = false ;
196+
197+ for arg in raw_args. iter ( ) . skip ( 1 ) {
198+ if !saw_double_dash {
199+ if arg == "--" {
200+ saw_double_dash = true ;
201+ others. push ( arg. clone ( ) ) ;
202+ continue ;
203+ }
204+
205+ if is_global_flag ( arg) {
206+ globals. push ( arg. clone ( ) ) ;
207+ continue ;
208+ }
209+ }
210+
211+ others. push ( arg. clone ( ) ) ;
212+ }
213+
214+ result. push ( raw_args[ 0 ] . clone ( ) ) ;
215+ result. extend ( globals) ;
216+ result. push ( OsString :: from ( "build" ) ) ;
217+ result. extend ( others) ;
218+ result
219+ }
220+
201221#[ cfg( test) ]
202222mod tests {
203223 use super :: * ;
224+ use log:: LevelFilter ;
204225 use std:: ffi:: OsString ;
205226
206227 fn parse ( args : & [ & str ] ) -> Result < cli:: Cli , clap:: Error > {
@@ -234,6 +255,17 @@ mod tests {
234255 assert ! ( matches!( cli. command, cli:: Command :: Watch ( _) ) ) ;
235256 }
236257
258+ #[ test]
259+ fn trailing_global_flag_is_treated_as_global ( ) {
260+ let cli = parse ( & [ "rescript" , "my-project" , "-v" ] ) . expect ( "expected build command" ) ;
261+
262+ assert_eq ! ( cli. verbose. log_level_filter( ) , LevelFilter :: Debug ) ;
263+ match cli. command {
264+ cli:: Command :: Build ( build_args) => assert_eq ! ( build_args. folder. folder, "my-project" ) ,
265+ other => panic ! ( "expected build command, got {other:?}" ) ,
266+ }
267+ }
268+
237269 #[ test]
238270 fn invalid_option_for_subcommand_does_not_fallback ( ) {
239271 let err = parse ( & [ "rescript" , "watch" , "--no-timing" ] ) . expect_err ( "expected watch parse failure" ) ;
0 commit comments