Implement new command execution logic · rust-lang/rust@a12f541 (original) (raw)

`@@ -41,7 +41,7 @@ use crate::core::builder::Kind;

`

41

41

`use crate::core::config::{flags, LldMode};

`

42

42

`use crate::core::config::{DryRun, Target};

`

43

43

`use crate::core::config::{LlvmLibunwind, TargetSelection};

`

44

``

`-

use crate::utils::exec::{BehaviorOnFailure, BootstrapCommand, OutputMode};

`

``

44

`+

use crate::utils::exec::{BehaviorOnFailure, BootstrapCommand, CommandOutput, OutputMode};

`

45

45

`use crate::utils::helpers::{self, dir_is_empty, exe, libdir, mtime, output, symlink_dir};

`

46

46

``

47

47

`mod core;

`

`@@ -958,6 +958,65 @@ impl Build {

`

958

958

`})

`

959

959

`}

`

960

960

``

``

961

`+

fn run_tracked(&self, command: BootstrapCommand) -> CommandOutput {

`

``

962

`+

if self.config.dry_run() {

`

``

963

`+

return CommandOutput::default();

`

``

964

`+

}

`

``

965

+

``

966

`+

self.verbose(|| println!("running: {command:?}"));

`

``

967

+

``

968

`+

let (output, print_error): (io::Result, bool) = match command.output_mode {

`

``

969

`+

mode @ (OutputMode::PrintAll | OutputMode::PrintOutput) => (

`

``

970

`+

command.command.status().map(|status| status.into()),

`

``

971

`+

matches!(mode, OutputMode::PrintAll),

`

``

972

`+

),

`

``

973

`+

OutputMode::SuppressOnSuccess => (command.command.output().map(|o| o.into()), true),

`

``

974

`+

};

`

``

975

+

``

976

`+

let output = match output {

`

``

977

`+

Ok(output) => output,

`

``

978

`+

Err(e) => fail(&format!("failed to execute command: {:?}\nerror: {}", command, e)),

`

``

979

`+

};

`

``

980

`+

if !output.is_success() {

`

``

981

`+

if print_error {

`

``

982

`+

println!(

`

``

983

`+

"\n\nCommand did not execute successfully.\

`

``

984

`+

\nExpected success, got: {}",

`

``

985

`+

output.status(),

`

``

986

`+

);

`

``

987

+

``

988

`+

if !self.is_verbose() {

`

``

989

`` +

println!("Add -v to see more details.\n");

``

``

990

`+

}

`

``

991

+

``

992

`+

self.verbose(|| {

`

``

993

`+

println!(

`

``

994

`+

"\nSTDOUT ----\n{}\n\

`

``

995

`+

STDERR ----\n{}\n",

`

``

996

`+

output.stdout(),

`

``

997

`+

output.stderr(),

`

``

998

`+

)

`

``

999

`+

});

`

``

1000

`+

}

`

``

1001

+

``

1002

`+

match command.failure_behavior {

`

``

1003

`+

BehaviorOnFailure::DelayFail => {

`

``

1004

`+

if self.fail_fast {

`

``

1005

`+

exit!(1);

`

``

1006

`+

}

`

``

1007

+

``

1008

`+

let mut failures = self.delayed_failures.borrow_mut();

`

``

1009

`+

failures.push(format!("{command:?}"));

`

``

1010

`+

}

`

``

1011

`+

BehaviorOnFailure::Exit => {

`

``

1012

`+

exit!(1);

`

``

1013

`+

}

`

``

1014

`+

BehaviorOnFailure::Ignore => {}

`

``

1015

`+

}

`

``

1016

`+

}

`

``

1017

`+

output

`

``

1018

`+

}

`

``

1019

+

961

1020

`/// Runs a command, printing out nice contextual information if it fails.

`

962

1021

`fn run(&self, cmd: &mut Command) {

`

963

1022

`self.run_cmd(BootstrapCommand::from(cmd).fail_fast().output_mode(

`