@@ -153,9 +153,26 @@ impl TryCmd {
153
153
}
154
154
155
155
fn parse_trycmd ( s : & str ) -> Result < Self , String > {
156
+ let mut cmdline = String :: new ( ) ;
157
+ let mut status = Some ( CommandStatus :: Success ) ;
158
+ for line in s. lines ( ) {
159
+ if let Some ( raw) = line. strip_prefix ( "$ " ) {
160
+ cmdline. clear ( ) ;
161
+ cmdline. push_str ( raw. trim ( ) ) ;
162
+ cmdline. push ( ' ' ) ;
163
+ } else if let Some ( raw) = line. strip_prefix ( "> " ) {
164
+ cmdline. push_str ( raw. trim ( ) ) ;
165
+ cmdline. push ( ' ' ) ;
166
+ } else if let Some ( raw) = line. strip_prefix ( "? " ) {
167
+ status = Some ( raw. trim ( ) . parse :: < CommandStatus > ( ) ?) ;
168
+ } else {
169
+ return Err ( format ! ( "Invalid line: `{}`" , line) ) ;
170
+ }
171
+ }
172
+
156
173
let mut env = Env :: default ( ) ;
157
174
158
- let mut iter = shlex:: Shlex :: new ( s . trim ( ) ) ;
175
+ let mut iter = shlex:: Shlex :: new ( cmdline . trim ( ) ) ;
159
176
let bin = loop {
160
177
let next = iter
161
178
. next ( )
@@ -171,6 +188,7 @@ impl TryCmd {
171
188
bin : Some ( Bin :: Name ( bin) ) ,
172
189
args : Some ( args) ,
173
190
env,
191
+ status,
174
192
..Default :: default ( )
175
193
} )
176
194
}
@@ -376,16 +394,33 @@ where
376
394
#[ serde( rename_all = "kebab-case" ) ]
377
395
#[ cfg_attr( feature = "schema" , derive( schemars:: JsonSchema ) ) ]
378
396
pub enum CommandStatus {
379
- Pass ,
380
- Fail ,
397
+ Success ,
398
+ Failed ,
381
399
Interrupted ,
382
- Skip ,
400
+ Skipped ,
383
401
Code ( i32 ) ,
384
402
}
385
403
386
404
impl Default for CommandStatus {
387
405
fn default ( ) -> Self {
388
- CommandStatus :: Pass
406
+ CommandStatus :: Success
407
+ }
408
+ }
409
+
410
+ impl std:: str:: FromStr for CommandStatus {
411
+ type Err = String ;
412
+
413
+ fn from_str ( s : & str ) -> Result < Self , Self :: Err > {
414
+ match s {
415
+ "success" => Ok ( Self :: Success ) ,
416
+ "failed" => Ok ( Self :: Failed ) ,
417
+ "interrupted" => Ok ( Self :: Interrupted ) ,
418
+ "skipped" => Ok ( Self :: Skipped ) ,
419
+ _ => s
420
+ . parse :: < i32 > ( )
421
+ . map ( Self :: Code )
422
+ . map_err ( |_| format ! ( "Expected an exit code, got {}" , s) ) ,
423
+ }
389
424
}
390
425
}
391
426
@@ -398,9 +433,10 @@ mod test {
398
433
let expected = TryCmd {
399
434
bin : Some ( Bin :: Name ( "cmd" . into ( ) ) ) ,
400
435
args : Some ( Args :: default ( ) ) ,
436
+ status : Some ( CommandStatus :: Success ) ,
401
437
..Default :: default ( )
402
438
} ;
403
- let actual = TryCmd :: parse_trycmd ( "cmd" ) . unwrap ( ) ;
439
+ let actual = TryCmd :: parse_trycmd ( "$ cmd" ) . unwrap ( ) ;
404
440
assert_eq ! ( expected, actual) ;
405
441
}
406
442
@@ -409,9 +445,22 @@ mod test {
409
445
let expected = TryCmd {
410
446
bin : Some ( Bin :: Name ( "cmd" . into ( ) ) ) ,
411
447
args : Some ( Args :: Split ( vec ! [ "arg1" . into( ) , "arg with space" . into( ) ] ) ) ,
448
+ status : Some ( CommandStatus :: Success ) ,
449
+ ..Default :: default ( )
450
+ } ;
451
+ let actual = TryCmd :: parse_trycmd ( "$ cmd arg1 'arg with space'" ) . unwrap ( ) ;
452
+ assert_eq ! ( expected, actual) ;
453
+ }
454
+
455
+ #[ test]
456
+ fn parse_trycmd_multi_line ( ) {
457
+ let expected = TryCmd {
458
+ bin : Some ( Bin :: Name ( "cmd" . into ( ) ) ) ,
459
+ args : Some ( Args :: Split ( vec ! [ "arg1" . into( ) , "arg with space" . into( ) ] ) ) ,
460
+ status : Some ( CommandStatus :: Success ) ,
412
461
..Default :: default ( )
413
462
} ;
414
- let actual = TryCmd :: parse_trycmd ( "cmd arg1 'arg with space'" ) . unwrap ( ) ;
463
+ let actual = TryCmd :: parse_trycmd ( "$ cmd arg1\n > 'arg with space'" ) . unwrap ( ) ;
415
464
assert_eq ! ( expected, actual) ;
416
465
}
417
466
@@ -428,9 +477,34 @@ mod test {
428
477
. collect ( ) ,
429
478
..Default :: default ( )
430
479
} ,
480
+ status : Some ( CommandStatus :: Success ) ,
481
+ ..Default :: default ( )
482
+ } ;
483
+ let actual = TryCmd :: parse_trycmd ( "$ KEY1=VALUE1 KEY2='VALUE2 with space' cmd" ) . unwrap ( ) ;
484
+ assert_eq ! ( expected, actual) ;
485
+ }
486
+
487
+ #[ test]
488
+ fn parse_trycmd_status ( ) {
489
+ let expected = TryCmd {
490
+ bin : Some ( Bin :: Name ( "cmd" . into ( ) ) ) ,
491
+ args : Some ( Args :: default ( ) ) ,
492
+ status : Some ( CommandStatus :: Skipped ) ,
493
+ ..Default :: default ( )
494
+ } ;
495
+ let actual = TryCmd :: parse_trycmd ( "$ cmd\n ? skipped" ) . unwrap ( ) ;
496
+ assert_eq ! ( expected, actual) ;
497
+ }
498
+
499
+ #[ test]
500
+ fn parse_trycmd_status_code ( ) {
501
+ let expected = TryCmd {
502
+ bin : Some ( Bin :: Name ( "cmd" . into ( ) ) ) ,
503
+ args : Some ( Args :: default ( ) ) ,
504
+ status : Some ( CommandStatus :: Code ( -1 ) ) ,
431
505
..Default :: default ( )
432
506
} ;
433
- let actual = TryCmd :: parse_trycmd ( "KEY1=VALUE1 KEY2='VALUE2 with space' cmd" ) . unwrap ( ) ;
507
+ let actual = TryCmd :: parse_trycmd ( "$ cmd\n ? -1 " ) . unwrap ( ) ;
434
508
assert_eq ! ( expected, actual) ;
435
509
}
436
510
@@ -498,10 +572,10 @@ mod test {
498
572
#[ test]
499
573
fn parse_toml_status_success ( ) {
500
574
let expected = TryCmd {
501
- status : Some ( CommandStatus :: Pass ) ,
575
+ status : Some ( CommandStatus :: Success ) ,
502
576
..Default :: default ( )
503
577
} ;
504
- let actual = TryCmd :: parse_toml ( "status = 'pass '" ) . unwrap ( ) ;
578
+ let actual = TryCmd :: parse_toml ( "status = 'success '" ) . unwrap ( ) ;
505
579
assert_eq ! ( expected, actual) ;
506
580
}
507
581
0 commit comments