diff --git a/src/bootstrap/src/utils/exec.rs b/src/bootstrap/src/utils/exec.rs index 545e059b5cf1..7b3ae3c9f758 100644 --- a/src/bootstrap/src/utils/exec.rs +++ b/src/bootstrap/src/utils/exec.rs @@ -77,7 +77,6 @@ pub struct CommandCacheKey { /// [allow_failure]: BootstrapCommand::allow_failure /// [delay_failure]: BootstrapCommand::delay_failure pub struct BootstrapCommand { - cache_key: CommandCacheKey, command: Command, pub failure_behavior: BehaviorOnFailure, // Run the command even during dry run @@ -91,17 +90,9 @@ pub struct BootstrapCommand { impl<'a> BootstrapCommand { #[track_caller] pub fn new>(program: S) -> Self { - Self { - should_cache: true, - cache_key: CommandCacheKey { - program: program.as_ref().to_os_string(), - ..CommandCacheKey::default() - }, - ..Command::new(program).into() - } + Self { should_cache: true, ..Command::new(program).into() } } pub fn arg>(&mut self, arg: S) -> &mut Self { - self.cache_key.args.push(arg.as_ref().to_os_string()); self.command.arg(arg.as_ref()); self } @@ -126,7 +117,6 @@ impl<'a> BootstrapCommand { K: AsRef, V: AsRef, { - self.cache_key.envs.push((key.as_ref().to_os_string(), val.as_ref().to_os_string())); self.command.env(key, val); self } @@ -145,7 +135,6 @@ impl<'a> BootstrapCommand { } pub fn current_dir>(&mut self, dir: P) -> &mut Self { - self.cache_key.cwd = Some(dir.as_ref().to_path_buf()); self.command.current_dir(dir); self } @@ -244,8 +233,8 @@ impl<'a> BootstrapCommand { } } - pub fn cache_key(&self) -> CommandCacheKey { - self.cache_key.clone() + pub fn cache_key(&self) -> Option { + (!self.should_cache).then(|| self.into()) } } @@ -260,9 +249,7 @@ impl From for BootstrapCommand { #[track_caller] fn from(command: Command) -> Self { let program = command.get_program().to_owned(); - Self { - cache_key: CommandCacheKey::default(), should_cache: false, command, failure_behavior: BehaviorOnFailure::Exit, @@ -272,6 +259,21 @@ impl From for BootstrapCommand { } } +impl From<&BootstrapCommand> for CommandCacheKey { + fn from(value: &BootstrapCommand) -> Self { + let command = &value.command; + CommandCacheKey { + program: command.get_program().into(), + args: command.get_args().map(OsStr::to_os_string).collect(), + envs: command + .get_envs() + .filter_map(|(k, v_opt)| v_opt.map(|v| (k.to_owned(), v.to_owned()))) + .collect(), + cwd: command.get_current_dir().map(Path::to_path_buf), + } + } +} + /// Represents the current status of `BootstrapCommand`. #[derive(Clone, PartialEq)] enum CommandStatus { diff --git a/src/bootstrap/src/utils/execution_context.rs b/src/bootstrap/src/utils/execution_context.rs index d7ea556c9ff7..3630ef4dd979 100644 --- a/src/bootstrap/src/utils/execution_context.rs +++ b/src/bootstrap/src/utils/execution_context.rs @@ -148,21 +148,24 @@ impl ExecutionContext { ) -> CommandOutput { let cache_key = command.cache_key(); - if command.should_cache() - && let Some(cached_output) = self.command_cache.get(&cache_key) + if let Some(cached_output) = cache_key.as_ref().and_then(|key| self.command_cache.get(key)) { command.mark_as_executed(); + if self.dry_run() && !command.run_always { return CommandOutput::default(); } + self.verbose(|| println!("Cache hit: {:?}", command)); return cached_output; } let output = self.start(command, stdout, stderr).wait_for_output(self); - if !self.dry_run() || command.run_always && command.should_cache() { - self.command_cache.insert(cache_key, output.clone()); + if !self.dry_run() || command.run_always { + if let Some(cache_key) = cache_key { + self.command_cache.insert(cache_key, output.clone()); + } } output