Skip to content

Commit 821d695

Browse files
committed
remove extra caching logic from run and re-structure the changes
1 parent 1e4cd7f commit 821d695

File tree

2 files changed

+31
-74
lines changed

2 files changed

+31
-74
lines changed

src/bootstrap/src/utils/exec.rs

Lines changed: 20 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,12 @@
22
//!
33
//! This module provides a structured way to execute and manage commands efficiently,
44
//! ensuring controlled failure handling and output management.
5-
#![allow(warnings)]
65
7-
use std::collections::HashMap;
86
use std::ffi::{OsStr, OsString};
97
use std::fmt::{Debug, Formatter};
10-
use std::hash::{Hash, Hasher};
8+
use std::hash::Hash;
119
use std::path::Path;
1210
use std::process::{Command, CommandArgs, CommandEnvs, ExitStatus, Output, Stdio};
13-
use std::sync::Mutex;
1411

1512
use build_helper::ci::CiEnv;
1613
use build_helper::drop_bomb::DropBomb;
@@ -59,7 +56,7 @@ impl OutputMode {
5956
pub struct CommandCacheKey {
6057
program: OsString,
6158
args: Vec<OsString>,
62-
envs: Vec<(OsString, OsString)>,
59+
envs: Vec<(OsString, Option<OsString>)>,
6360
cwd: Option<PathBuf>,
6461
}
6562

@@ -90,18 +87,14 @@ pub struct BootstrapCommand {
9087
impl<'a> BootstrapCommand {
9188
#[track_caller]
9289
pub fn new<S: AsRef<OsStr>>(program: S) -> Self {
93-
Self { should_cache: true, ..Command::new(program).into() }
90+
Command::new(program).into()
9491
}
9592
pub fn arg<S: AsRef<OsStr>>(&mut self, arg: S) -> &mut Self {
9693
self.command.arg(arg.as_ref());
9794
self
9895
}
9996

100-
pub fn should_cache(&self) -> bool {
101-
self.should_cache
102-
}
103-
104-
pub fn cache_never(&mut self) -> &mut Self {
97+
pub fn do_not_cache(&mut self) -> &mut Self {
10598
self.should_cache = false;
10699
self
107100
}
@@ -111,9 +104,7 @@ impl<'a> BootstrapCommand {
111104
I: IntoIterator<Item = S>,
112105
S: AsRef<OsStr>,
113106
{
114-
args.into_iter().for_each(|arg| {
115-
self.arg(arg);
116-
});
107+
self.command.args(args);
117108
self
118109
}
119110

@@ -207,7 +198,7 @@ impl<'a> BootstrapCommand {
207198
// command will be handled. Caching must also be avoided here, as the inner command could be
208199
// modified externally without us being aware.
209200
self.mark_as_executed();
210-
self.cache_never();
201+
self.do_not_cache();
211202
&mut self.command
212203
}
213204

@@ -235,7 +226,19 @@ impl<'a> BootstrapCommand {
235226
}
236227

237228
pub fn cache_key(&self) -> Option<CommandCacheKey> {
238-
(!self.should_cache).then(|| self.into())
229+
if !self.should_cache {
230+
return None;
231+
}
232+
let command = &self.command;
233+
Some(CommandCacheKey {
234+
program: command.get_program().into(),
235+
args: command.get_args().map(OsStr::to_os_string).collect(),
236+
envs: command
237+
.get_envs()
238+
.map(|(k, v)| (k.to_os_string(), v.map(|val| val.to_os_string())))
239+
.collect(),
240+
cwd: command.get_current_dir().map(Path::to_path_buf),
241+
})
239242
}
240243
}
241244

@@ -251,7 +254,7 @@ impl From<Command> for BootstrapCommand {
251254
fn from(command: Command) -> Self {
252255
let program = command.get_program().to_owned();
253256
Self {
254-
should_cache: false,
257+
should_cache: true,
255258
command,
256259
failure_behavior: BehaviorOnFailure::Exit,
257260
run_always: false,
@@ -260,21 +263,6 @@ impl From<Command> for BootstrapCommand {
260263
}
261264
}
262265

263-
impl From<&BootstrapCommand> for CommandCacheKey {
264-
fn from(value: &BootstrapCommand) -> Self {
265-
let command = &value.command;
266-
CommandCacheKey {
267-
program: command.get_program().into(),
268-
args: command.get_args().map(OsStr::to_os_string).collect(),
269-
envs: command
270-
.get_envs()
271-
.filter_map(|(k, v_opt)| v_opt.map(|v| (k.to_owned(), v.to_owned())))
272-
.collect(),
273-
cwd: command.get_current_dir().map(Path::to_path_buf),
274-
}
275-
}
276-
}
277-
278266
/// Represents the current status of `BootstrapCommand`.
279267
#[derive(Clone, PartialEq)]
280268
enum CommandStatus {

src/bootstrap/src/utils/execution_context.rs

Lines changed: 11 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
//! This module provides the [`ExecutionContext`] type, which holds global configuration
44
//! relevant during the execution of commands in bootstrap. This includes dry-run
55
//! mode, verbosity level, and behavior on failure.
6-
#![allow(warnings)]
76
use std::collections::HashMap;
87
use std::panic::Location;
98
use std::process::Child;
@@ -46,10 +45,6 @@ pub struct DeferredCommand<'a> {
4645
}
4746

4847
impl CommandCache {
49-
pub fn new() -> Self {
50-
Self { cache: Mutex::new(HashMap::new()) }
51-
}
52-
5348
pub fn get(&self, key: &CommandCacheKey) -> Option<CommandOutput> {
5449
self.cache.lock().unwrap().get(key).cloned()
5550
}
@@ -133,7 +128,7 @@ impl ExecutionContext {
133128
{
134129
command.mark_as_executed();
135130

136-
self.verbose(|| println!("Cache hit: {:?}", command));
131+
self.verbose(|| println!("Cache hit: {command:?}"));
137132

138133
return DeferredCommand { state: CommandState::Cached(cached_output) };
139134
}
@@ -191,29 +186,7 @@ impl ExecutionContext {
191186
stdout: OutputMode,
192187
stderr: OutputMode,
193188
) -> CommandOutput {
194-
let cache_key = command.cache_key();
195-
196-
if let Some(cached_output) = cache_key.as_ref().and_then(|key| self.command_cache.get(key))
197-
{
198-
command.mark_as_executed();
199-
200-
if self.dry_run() && !command.run_always {
201-
return CommandOutput::default();
202-
}
203-
204-
self.verbose(|| println!("Cache hit: {:?}", command));
205-
return cached_output;
206-
}
207-
208-
let output = self.start(command, stdout, stderr).wait_for_output(self);
209-
210-
if !self.dry_run() || command.run_always {
211-
if let Some(cache_key) = cache_key {
212-
self.command_cache.insert(cache_key, output.clone());
213-
}
214-
}
215-
216-
output
189+
self.start(command, stdout, stderr).wait_for_output(self)
217190
}
218191

219192
fn fail(&self, message: &str, output: CommandOutput) -> ! {
@@ -247,7 +220,7 @@ impl AsRef<ExecutionContext> for ExecutionContext {
247220
}
248221

249222
impl<'a> DeferredCommand<'a> {
250-
pub fn wait_for_output(mut self, exec_ctx: impl AsRef<ExecutionContext>) -> CommandOutput {
223+
pub fn wait_for_output(self, exec_ctx: impl AsRef<ExecutionContext>) -> CommandOutput {
251224
match self.state {
252225
CommandState::Cached(output) => output,
253226
CommandState::Deferred { process, command, stdout, stderr, executed_at, cache_key } => {
@@ -256,11 +229,10 @@ impl<'a> DeferredCommand<'a> {
256229
let output =
257230
Self::execute_process(process, command, stdout, stderr, executed_at, exec_ctx);
258231

259-
if (!exec_ctx.dry_run() || command.run_always)
260-
&& cache_key.is_some()
261-
&& output.status().is_some()
262-
{
263-
exec_ctx.command_cache.insert(cache_key.unwrap(), output.clone());
232+
if !exec_ctx.dry_run() || command.run_always {
233+
if let (Some(cache_key), Some(_)) = (&cache_key, output.status()) {
234+
exec_ctx.command_cache.insert(cache_key.clone(), output.clone());
235+
}
264236
}
265237

266238
output
@@ -276,8 +248,6 @@ impl<'a> DeferredCommand<'a> {
276248
executed_at: &'a std::panic::Location<'a>,
277249
exec_ctx: &ExecutionContext,
278250
) -> CommandOutput {
279-
let exec_ctx = exec_ctx.as_ref();
280-
281251
let process = match process.take() {
282252
Some(p) => p,
283253
None => return CommandOutput::default(),
@@ -301,11 +271,11 @@ impl<'a> DeferredCommand<'a> {
301271
writeln!(
302272
message,
303273
r#"
304-
Command {:?} did not execute successfully.
274+
Command {command:?} did not execute successfully.
305275
Expected success, got {}
306276
Created at: {created_at}
307277
Executed at: {executed_at}"#,
308-
command, result.status,
278+
result.status,
309279
)
310280
.unwrap();
311281

@@ -326,9 +296,8 @@ Executed at: {executed_at}"#,
326296

327297
writeln!(
328298
message,
329-
"\n\nCommand {:?} did not execute successfully.\
330-
\nIt was not possible to execute the command: {e:?}",
331-
command
299+
"\n\nCommand {command:?} did not execute successfully.\
300+
\nIt was not possible to execute the command: {e:?}"
332301
)
333302
.unwrap();
334303

0 commit comments

Comments
 (0)