Print command creation and execution location when it fails

This should make it quicker to debug command failures.
This commit is contained in:
Jakub Beránek 2024-07-04 20:24:37 +02:00 committed by Jakub Beránek
parent cefd5b3834
commit 542344f5bb
No known key found for this signature in database
GPG key ID: 909CD0D26483516B
3 changed files with 23 additions and 4 deletions

View file

@ -937,13 +937,19 @@ impl Build {
/// Execute a command and return its output.
/// This method should be used for all command executions in bootstrap.
#[track_caller]
fn run(&self, command: &mut BootstrapCommand) -> CommandOutput {
command.mark_as_executed();
if self.config.dry_run() && !command.run_always {
return CommandOutput::default();
}
self.verbose(|| println!("running: {command:?}"));
let created_at = command.get_created_location();
let executed_at = std::panic::Location::caller();
self.verbose(|| {
println!("running: {command:?} (created at {created_at}, executed at {executed_at})")
});
let stdout = command.stdout.stdio();
command.as_command_mut().stdout(stdout);
@ -962,8 +968,11 @@ impl Build {
Ok(output) => {
writeln!(
message,
"\n\nCommand {command:?} did not execute successfully.\
\nExpected success, got: {}",
r#"
Command {command:?} did not execute successfully.
Expected success, got {}
Created at: {created_at}
Executed at: {executed_at}"#,
output.status,
)
.unwrap();

View file

@ -160,17 +160,23 @@ impl BootstrapCommand {
&mut self.command
}
/// Mark the command as being executd, disarming the drop bomb.
/// Mark the command as being executed, disarming the drop bomb.
/// If this method is not called before the command is dropped, its drop will panic.
pub fn mark_as_executed(&mut self) {
self.drop_bomb.defuse();
}
/// Returns the source code location where this command was created.
pub fn get_created_location(&self) -> std::panic::Location<'static> {
self.drop_bomb.get_created_location()
}
}
impl From<Command> for BootstrapCommand {
#[track_caller]
fn from(command: Command) -> Self {
let program = command.get_program().to_owned();
Self {
command,
failure_behavior: BehaviorOnFailure::Exit,

View file

@ -31,6 +31,10 @@ impl DropBomb {
}
}
pub fn get_created_location(&self) -> panic::Location<'static> {
self.armed_location
}
/// Defuse the [`DropBomb`]. This will prevent the drop bomb from panicking when dropped.
pub fn defuse(&mut self) {
self.defused = true;