@@ -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 } ;
@@ -39,7 +40,7 @@ use crate::core::config::flags;
3940use crate :: core:: config:: { DryRun , Target } ;
4041use crate :: core:: config:: { LlvmLibunwind , TargetSelection } ;
4142use crate :: utils:: cache:: { Interned , INTERNER } ;
42- use crate :: utils:: exec:: { BehaviorOnFailure , BootstrapCommand } ;
43+ use crate :: utils:: exec:: { BehaviorOnFailure , BootstrapCommand , OutputMode } ;
4344use crate :: utils:: helpers:: { self , dir_is_empty, exe, libdir, mtime, output, symlink_dir} ;
4445
4546mod core;
@@ -919,41 +920,78 @@ impl Build {
919920
920921 /// Runs a command, printing out nice contextual information if it fails.
921922 fn run ( & self , cmd : & mut Command ) {
922- // FIXME: output mode -> status + err if self.is_verbose()
923- let cmd: BootstrapCommand < ' _ > = cmd. into ( ) ;
924- self . run_cmd ( cmd. fail_fast ( ) ) ;
923+ self . run_cmd ( BootstrapCommand :: from ( cmd) . fail_fast ( ) . output_mode (
924+ match self . is_verbose ( ) {
925+ true => OutputMode :: PrintAll ,
926+ false => OutputMode :: PrintOutput ,
927+ } ,
928+ ) ) ;
929+ }
930+
931+ /// Runs a command, printing out contextual info if it fails, and delaying errors until the build finishes.
932+ pub ( crate ) fn run_delaying_failure ( & self , cmd : & mut Command ) -> bool {
933+ self . run_cmd ( BootstrapCommand :: from ( cmd) . delay_failure ( ) . output_mode (
934+ match self . is_verbose ( ) {
935+ true => OutputMode :: PrintAll ,
936+ false => OutputMode :: PrintOutput ,
937+ } ,
938+ ) )
925939 }
926940
927941 /// Runs a command, printing out nice contextual information if it fails.
928942 fn run_quiet ( & self , cmd : & mut Command ) {
929- // FIXME: output mode -> output + err
930- let cmd: BootstrapCommand < ' _ > = cmd. into ( ) ;
931- self . run_cmd ( cmd. fail_fast ( ) ) ;
943+ self . run_cmd ( BootstrapCommand :: from ( cmd) . fail_fast ( ) . output_mode ( OutputMode :: Suppress ) ) ;
932944 }
933945
934946 /// Runs a command, printing out nice contextual information if it fails.
935947 /// Exits if the command failed to execute at all, otherwise returns its
936948 /// `status.success()`.
937949 fn run_quiet_delaying_failure ( & self , cmd : & mut Command ) -> bool {
938- // FIXME: output mode -> output + err
939- let cmd: BootstrapCommand < ' _ > = cmd. into ( ) ;
940- self . run_cmd ( cmd. delay_failure ( ) )
941- }
942-
943- /// Runs a command, printing out contextual info if it fails, and delaying errors until the build finishes.
944- pub ( crate ) fn run_delaying_failure ( & self , cmd : & mut Command ) -> bool {
945- // FIXME: output mode -> status + err if self.is_verbose()
946- let cmd: BootstrapCommand < ' _ > = cmd. into ( ) ;
947- self . run_cmd ( cmd. delay_failure ( ) )
950+ self . run_cmd ( BootstrapCommand :: from ( cmd) . delay_failure ( ) . output_mode ( OutputMode :: Suppress ) )
948951 }
949952
950953 /// A centralized function for running commands that do not return output.
951954 pub ( crate ) fn run_cmd < ' a , C : Into < BootstrapCommand < ' a > > > ( & self , cmd : C ) -> bool {
955+ if self . config . dry_run ( ) {
956+ return true ;
957+ }
958+
952959 let command = cmd. into ( ) ;
953960 self . verbose ( & format ! ( "running: {command:?}" ) ) ;
954961
955- #[ allow( deprecated) ] // can't use Build::try_run, that's us
956- let result = self . config . try_run ( command. command ) ;
962+ let ( output, print_error) = match command. output_mode {
963+ mode @ ( OutputMode :: PrintAll | OutputMode :: PrintOutput ) => (
964+ command. command . status ( ) . map ( |status| Output {
965+ status,
966+ stdout : Vec :: new ( ) ,
967+ stderr : Vec :: new ( ) ,
968+ } ) ,
969+ matches ! ( mode, OutputMode :: PrintAll ) ,
970+ ) ,
971+ OutputMode :: Suppress => ( command. command . output ( ) , true ) ,
972+ } ;
973+
974+ let output = match output {
975+ Ok ( output) => output,
976+ Err ( e) => fail ( & format ! ( "failed to execute command: {:?}\n error: {}" , command, e) ) ,
977+ } ;
978+ let result = if !output. status . success ( ) {
979+ if print_error {
980+ println ! (
981+ "\n \n command did not execute successfully: {:?}\n \
982+ expected success, got: {}\n \n \
983+ stdout ----\n {}\n \
984+ stderr ----\n {}\n \n ",
985+ command. command,
986+ output. status,
987+ String :: from_utf8_lossy( & output. stdout) ,
988+ String :: from_utf8_lossy( & output. stderr)
989+ ) ;
990+ }
991+ Err ( ( ) )
992+ } else {
993+ Ok ( ( ) )
994+ } ;
957995
958996 match result {
959997 Ok ( _) => true ,
0 commit comments