@@ -23,11 +23,12 @@ use std::fmt::Display;
2323use std:: fs:: { self , File } ;
2424use std:: io;
2525use std:: path:: { Path , PathBuf } ;
26- use std:: process:: { Command , Stdio } ;
26+ use std:: process:: { Command , Output , Stdio } ;
2727use std:: str;
2828
2929use build_helper:: ci:: { gha, CiEnv } ;
3030use build_helper:: exit;
31+ use build_helper:: util:: fail;
3132use filetime:: FileTime ;
3233use once_cell:: sync:: OnceCell ;
3334use termcolor:: { ColorChoice , StandardStream , WriteColor } ;
@@ -40,9 +41,9 @@ pub use crate::builder::PathSet;
4041use crate :: cache:: { Interned , INTERNER } ;
4142pub use crate :: config:: Config ;
4243use crate :: config:: { LlvmLibunwind , TargetSelection } ;
43- use crate :: exec:: { BehaviorOnFailure , BootstrapCommand } ;
44+ use crate :: exec:: { BehaviorOnFailure , BootstrapCommand , OutputMode } ;
4445pub use crate :: flags:: Subcommand ;
45- use crate :: util:: { dir_is_empty, exe, libdir, mtime, output, run , symlink_dir} ;
46+ use crate :: util:: { dir_is_empty, exe, libdir, mtime, output, symlink_dir} ;
4647
4748mod builder;
4849mod cache;
@@ -965,41 +966,78 @@ impl Build {
965966
966967 /// Runs a command, printing out nice contextual information if it fails.
967968 fn run ( & self , cmd : & mut Command ) {
968- // FIXME: output mode -> status + err if self.is_verbose()
969- let cmd: BootstrapCommand < ' _ > = cmd. into ( ) ;
970- self . run_cmd ( cmd. fail_fast ( ) ) ;
969+ self . run_cmd ( BootstrapCommand :: from ( cmd) . fail_fast ( ) . output_mode (
970+ match self . is_verbose ( ) {
971+ true => OutputMode :: PrintAll ,
972+ false => OutputMode :: PrintOutput ,
973+ } ,
974+ ) ) ;
975+ }
976+
977+ /// Runs a command, printing out contextual info if it fails, and delaying errors until the build finishes.
978+ pub ( crate ) fn run_delaying_failure ( & self , cmd : & mut Command ) -> bool {
979+ self . run_cmd ( BootstrapCommand :: from ( cmd) . delay_failure ( ) . output_mode (
980+ match self . is_verbose ( ) {
981+ true => OutputMode :: PrintAll ,
982+ false => OutputMode :: PrintOutput ,
983+ } ,
984+ ) )
971985 }
972986
973987 /// Runs a command, printing out nice contextual information if it fails.
974988 fn run_quiet ( & self , cmd : & mut Command ) {
975- // FIXME: output mode -> output + err
976- let cmd: BootstrapCommand < ' _ > = cmd. into ( ) ;
977- self . run_cmd ( cmd. fail_fast ( ) ) ;
989+ self . run_cmd ( BootstrapCommand :: from ( cmd) . fail_fast ( ) . output_mode ( OutputMode :: Suppress ) ) ;
978990 }
979991
980992 /// Runs a command, printing out nice contextual information if it fails.
981993 /// Exits if the command failed to execute at all, otherwise returns its
982994 /// `status.success()`.
983995 fn run_quiet_delaying_failure ( & self , cmd : & mut Command ) -> bool {
984- // FIXME: output mode -> output + err
985- let cmd: BootstrapCommand < ' _ > = cmd. into ( ) ;
986- self . run_cmd ( cmd. delay_failure ( ) )
987- }
988-
989- /// Runs a command, printing out contextual info if it fails, and delaying errors until the build finishes.
990- pub ( crate ) fn run_delaying_failure ( & self , cmd : & mut Command ) -> bool {
991- // FIXME: output mode -> status + err if self.is_verbose()
992- let cmd: BootstrapCommand < ' _ > = cmd. into ( ) ;
993- self . run_cmd ( cmd. delay_failure ( ) )
996+ self . run_cmd ( BootstrapCommand :: from ( cmd) . delay_failure ( ) . output_mode ( OutputMode :: Suppress ) )
994997 }
995998
996999 /// A centralized function for running commands that do not return output.
9971000 pub ( crate ) fn run_cmd < ' a , C : Into < BootstrapCommand < ' a > > > ( & self , cmd : C ) -> bool {
1001+ if self . config . dry_run ( ) {
1002+ return true ;
1003+ }
1004+
9981005 let command = cmd. into ( ) ;
9991006 self . verbose ( & format ! ( "running: {command:?}" ) ) ;
10001007
1001- #[ allow( deprecated) ] // can't use Build::try_run, that's us
1002- let result = self . config . try_run ( command. command ) ;
1008+ let ( output, print_error) = match command. output_mode {
1009+ mode @ ( OutputMode :: PrintAll | OutputMode :: PrintOutput ) => (
1010+ command. command . status ( ) . map ( |status| Output {
1011+ status,
1012+ stdout : Vec :: new ( ) ,
1013+ stderr : Vec :: new ( ) ,
1014+ } ) ,
1015+ matches ! ( mode, OutputMode :: PrintAll ) ,
1016+ ) ,
1017+ OutputMode :: Suppress => ( command. command . output ( ) , true ) ,
1018+ } ;
1019+
1020+ let output = match output {
1021+ Ok ( output) => output,
1022+ Err ( e) => fail ( & format ! ( "failed to execute command: {:?}\n error: {}" , command, e) ) ,
1023+ } ;
1024+ let result = if !output. status . success ( ) {
1025+ if print_error {
1026+ println ! (
1027+ "\n \n command did not execute successfully: {:?}\n \
1028+ expected success, got: {}\n \n \
1029+ stdout ----\n {}\n \
1030+ stderr ----\n {}\n \n ",
1031+ command. command,
1032+ output. status,
1033+ String :: from_utf8_lossy( & output. stdout) ,
1034+ String :: from_utf8_lossy( & output. stderr)
1035+ ) ;
1036+ }
1037+ Err ( ( ) )
1038+ } else {
1039+ Ok ( ( ) )
1040+ } ;
10031041
10041042 match result {
10051043 Ok ( _) => true ,
0 commit comments