@@ -13,7 +13,9 @@ use std::fmt::{Debug, Formatter};
13
13
use std:: hash:: Hash ;
14
14
use std:: panic:: Location ;
15
15
use std:: path:: Path ;
16
- use std:: process:: { Child , Command , CommandArgs , CommandEnvs , ExitStatus , Output , Stdio } ;
16
+ use std:: process:: {
17
+ Child , ChildStderr , ChildStdout , Command , CommandArgs , CommandEnvs , ExitStatus , Output , Stdio ,
18
+ } ;
17
19
use std:: sync:: { Arc , Mutex } ;
18
20
19
21
use build_helper:: ci:: CiEnv ;
@@ -449,6 +451,12 @@ enum CommandState<'a> {
449
451
} ,
450
452
}
451
453
454
+ pub struct CommandStreaming {
455
+ child : Child ,
456
+ pub stdout : Option < ChildStdout > ,
457
+ pub stderr : Option < ChildStderr > ,
458
+ }
459
+
452
460
#[ must_use]
453
461
pub struct DeferredCommand < ' a > {
454
462
state : CommandState < ' a > ,
@@ -625,7 +633,48 @@ impl AsRef<ExecutionContext> for ExecutionContext {
625
633
}
626
634
}
627
635
636
+ impl CommandStreaming {
637
+ pub fn wait ( mut self ) -> Result < ExitStatus , std:: io:: Error > {
638
+ self . child . wait ( )
639
+ }
640
+
641
+ pub fn wait_with_output ( self ) -> Result < Output , std:: io:: Error > {
642
+ self . child . wait_with_output ( )
643
+ }
644
+ }
645
+
628
646
impl < ' a > DeferredCommand < ' a > {
647
+ pub fn stream ( self ) -> Option < CommandStreaming > {
648
+ if let CommandState :: Deferred {
649
+ process,
650
+ command,
651
+ stdout : _,
652
+ stderr : _,
653
+ executed_at : _,
654
+ cache_key : _,
655
+ } = self . state
656
+ {
657
+ command. mark_as_executed ( ) ;
658
+
659
+ let child = match process {
660
+ Some ( child) => child,
661
+ None => {
662
+ return None ;
663
+ }
664
+ } ;
665
+
666
+ let mut child = match child {
667
+ Ok ( child) => child,
668
+ Err ( e) => panic ! ( "failed to execute command: {:?}\n ERROR: {e}" , command) ,
669
+ } ;
670
+
671
+ let stdout = child. stdout . take ( ) ;
672
+ let stderr = child. stderr . take ( ) ;
673
+ return Some ( CommandStreaming { child, stdout, stderr } ) ;
674
+ }
675
+ None
676
+ }
677
+
629
678
pub fn wait_for_output ( self , exec_ctx : impl AsRef < ExecutionContext > ) -> CommandOutput {
630
679
match self . state {
631
680
CommandState :: Cached ( output) => output,
0 commit comments