@@ -23,11 +23,12 @@ use std::fmt::Display;
23
23
use std:: fs:: { self , File } ;
24
24
use std:: io;
25
25
use std:: path:: { Path , PathBuf } ;
26
- use std:: process:: { Command , Stdio } ;
26
+ use std:: process:: { Command , Output , Stdio } ;
27
27
use std:: str;
28
28
29
29
use build_helper:: ci:: { gha, CiEnv } ;
30
30
use build_helper:: exit;
31
+ use build_helper:: util:: fail;
31
32
use filetime:: FileTime ;
32
33
use once_cell:: sync:: OnceCell ;
33
34
use termcolor:: { ColorChoice , StandardStream , WriteColor } ;
@@ -40,9 +41,9 @@ pub use crate::builder::PathSet;
40
41
use crate :: cache:: { Interned , INTERNER } ;
41
42
pub use crate :: config:: Config ;
42
43
use crate :: config:: { LlvmLibunwind , TargetSelection } ;
43
- use crate :: exec:: { BehaviorOnFailure , BootstrapCommand } ;
44
+ use crate :: exec:: { BehaviorOnFailure , BootstrapCommand , OutputMode } ;
44
45
pub 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} ;
46
47
47
48
mod builder;
48
49
mod cache;
@@ -965,41 +966,78 @@ impl Build {
965
966
966
967
/// Runs a command, printing out nice contextual information if it fails.
967
968
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
+ ) )
971
985
}
972
986
973
987
/// Runs a command, printing out nice contextual information if it fails.
974
988
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 ) ) ;
978
990
}
979
991
980
992
/// Runs a command, printing out nice contextual information if it fails.
981
993
/// Exits if the command failed to execute at all, otherwise returns its
982
994
/// `status.success()`.
983
995
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 ) )
994
997
}
995
998
996
999
/// A centralized function for running commands that do not return output.
997
1000
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
+
998
1005
let command = cmd. into ( ) ;
999
1006
self . verbose ( & format ! ( "running: {command:?}" ) ) ;
1000
1007
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
+ } ;
1003
1041
1004
1042
match result {
1005
1043
Ok ( _) => true ,
0 commit comments