11use crate :: Build ;
2+ use build_helper:: drop_bomb:: DropBomb ;
23use std:: ffi:: OsStr ;
34use std:: path:: Path ;
45use std:: process:: { Command , CommandArgs , CommandEnvs , ExitStatus , Output , Stdio } ;
@@ -61,9 +62,13 @@ pub struct BootstrapCommand {
6162 pub stderr : OutputMode ,
6263 // Run the command even during dry run
6364 pub run_always : bool ,
65+ // This field makes sure that each command is executed (or disarmed) before it is dropped,
66+ // to avoid forgetting to execute a command.
67+ drop_bomb : DropBomb ,
6468}
6569
6670impl BootstrapCommand {
71+ #[ track_caller]
6772 pub fn new < S : AsRef < OsStr > > ( program : S ) -> Self {
6873 Command :: new ( program) . into ( )
6974 }
@@ -149,18 +154,30 @@ impl BootstrapCommand {
149154 /// Provides access to the stdlib Command inside.
150155 /// All usages of this function should be eventually removed from bootstrap.
151156 pub fn as_command_mut ( & mut self ) -> & mut Command {
157+ // We don't know what will happen with the returned command, so we need to mark this
158+ // command as executed proactively.
159+ self . mark_as_executed ( ) ;
152160 & mut self . command
153161 }
162+
163+ /// Mark the command as being executd, disarming the drop bomb.
164+ /// If this method is not called before the command is dropped, its drop will panic.
165+ pub fn mark_as_executed ( & mut self ) {
166+ self . drop_bomb . defuse ( ) ;
167+ }
154168}
155169
156170impl From < Command > for BootstrapCommand {
171+ #[ track_caller]
157172 fn from ( command : Command ) -> Self {
173+ let program = command. get_program ( ) . to_owned ( ) ;
158174 Self {
159175 command,
160176 failure_behavior : BehaviorOnFailure :: Exit ,
161177 stdout : OutputMode :: Print ,
162178 stderr : OutputMode :: Print ,
163179 run_always : false ,
180+ drop_bomb : DropBomb :: arm ( program) ,
164181 }
165182 }
166183}
@@ -175,6 +192,7 @@ enum CommandStatus {
175192
176193/// Create a new BootstrapCommand. This is a helper function to make command creation
177194/// shorter than `BootstrapCommand::new`.
195+ #[ track_caller]
178196#[ must_use]
179197pub fn command < S : AsRef < OsStr > > ( program : S ) -> BootstrapCommand {
180198 BootstrapCommand :: new ( program)
0 commit comments