@@ -439,6 +439,19 @@ pub fn cargo_exe() -> PathBuf {
439
439
*
440
440
*/
441
441
442
+ /// This is the raw output from the process.
443
+ ///
444
+ /// This is similar to `std::process::Output`, however the `status` is
445
+ /// translated to the raw `code`. This is necessary because `ProcessError`
446
+ /// does not have access to the raw `ExitStatus` because `ProcessError` needs
447
+ /// to be serializable (for the Rustc cache), and `ExitStatus` does not
448
+ /// provide a constructor.
449
+ pub struct RawOutput {
450
+ pub code : Option < i32 > ,
451
+ pub stdout : Vec < u8 > ,
452
+ pub stderr : Vec < u8 > ,
453
+ }
454
+
442
455
#[ must_use]
443
456
#[ derive( Clone ) ]
444
457
pub struct Execs {
@@ -728,6 +741,25 @@ impl Execs {
728
741
}
729
742
}
730
743
744
+ /// Runs the process, checks the expected output, and returns the first
745
+ /// JSON object on stdout.
746
+ #[ track_caller]
747
+ pub fn run_json ( & mut self ) -> serde_json:: Value {
748
+ self . ran = true ;
749
+ let p = ( & self . process_builder ) . clone ( ) . unwrap ( ) ;
750
+ match self . match_process ( & p) {
751
+ Err ( e) => panic ! ( "\n {}" , e) ,
752
+ Ok ( output) => serde_json:: from_slice ( & output. stdout ) . unwrap_or_else ( |e| {
753
+ panic ! (
754
+ "\n failed to parse JSON: {}\n \
755
+ output was:\n {}\n ",
756
+ e,
757
+ String :: from_utf8_lossy( & output. stdout)
758
+ ) ;
759
+ } ) ,
760
+ }
761
+ }
762
+
731
763
#[ track_caller]
732
764
pub fn run_output ( & mut self , output : & Output ) {
733
765
self . ran = true ;
@@ -763,7 +795,7 @@ impl Execs {
763
795
}
764
796
}
765
797
766
- fn match_process ( & self , process : & ProcessBuilder ) -> Result < ( ) > {
798
+ fn match_process ( & self , process : & ProcessBuilder ) -> Result < RawOutput > {
767
799
println ! ( "running {}" , process) ;
768
800
let res = if self . stream_output {
769
801
if is_ci ( ) {
@@ -785,7 +817,14 @@ impl Execs {
785
817
} ;
786
818
787
819
match res {
788
- Ok ( out) => self . match_output ( & out) ,
820
+ Ok ( out) => {
821
+ self . match_output ( & out) ?;
822
+ return Ok ( RawOutput {
823
+ stdout : out. stdout ,
824
+ stderr : out. stderr ,
825
+ code : out. status . code ( ) ,
826
+ } ) ;
827
+ }
789
828
Err ( e) => {
790
829
if let Some ( ProcessError {
791
830
stdout : Some ( stdout) ,
@@ -794,10 +833,14 @@ impl Execs {
794
833
..
795
834
} ) = e. downcast_ref :: < ProcessError > ( )
796
835
{
797
- return self
798
- . match_status ( * code, stdout, stderr)
836
+ self . match_status ( * code, stdout, stderr)
799
837
. and ( self . match_stdout ( stdout, stderr) )
800
- . and ( self . match_stderr ( stdout, stderr) ) ;
838
+ . and ( self . match_stderr ( stdout, stderr) ) ?;
839
+ return Ok ( RawOutput {
840
+ stdout : stdout. to_vec ( ) ,
841
+ stderr : stderr. to_vec ( ) ,
842
+ code : * code,
843
+ } ) ;
801
844
}
802
845
bail ! ( "could not exec process {}: {:?}" , process, e)
803
846
}
0 commit comments