Skip to content

Commit bdf7051

Browse files
authored
fix: workspace.root in exec blocks (#340)
* fix: workspace.root in exec blocks * feedback;
1 parent fb5a6c0 commit bdf7051

File tree

2 files changed

+53
-22
lines changed

2 files changed

+53
-22
lines changed

crates/atuin-desktop-runtime/src/context/resolution.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,13 @@ impl ContextResolver {
115115
resolver
116116
}
117117

118+
/// Push multiple blocks to the resolver
119+
pub fn push_blocks(&mut self, blocks: &[DocumentBlock]) {
120+
for block in blocks {
121+
self.push_block(block);
122+
}
123+
}
124+
118125
/// Test-only constructor to create a resolver with specific vars
119126
#[cfg(test)]
120127
pub fn with_vars(vars: HashMap<String, String>) -> Self {

crates/atuin-desktop-runtime/src/document/mod.rs

Lines changed: 46 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -326,10 +326,19 @@ impl Document {
326326

327327
/// Get the current context resolver (includes all blocks and parent context)
328328
pub fn get_context_resolver(&self) -> ContextResolver {
329-
match &self.parent_context {
330-
Some(parent) => ContextResolver::from_blocks_with_parent(&self.blocks, parent),
331-
None => ContextResolver::from_blocks(&self.blocks),
329+
let mut resolver = match &self.parent_context {
330+
Some(parent) => ContextResolver::from_parent(parent),
331+
None => ContextResolver::new(),
332+
};
333+
334+
if let Some(ref workspace_root) = self.workspace_root {
335+
let mut workspace_context = HashMap::new();
336+
workspace_context.insert("root".to_string(), workspace_root.clone());
337+
resolver.add_extra_template_context("workspace".to_string(), workspace_context);
332338
}
339+
340+
resolver.push_blocks(&self.blocks);
341+
resolver
333342
}
334343

335344
/// Build an execution context for a block, capturing all context from blocks above it
@@ -353,31 +362,35 @@ impl Document {
353362
.get_block_index(block_id)
354363
.ok_or(DocumentError::BlockNotFound(*block_id))?;
355364

356-
// Build context resolver from all blocks above this one (with parent context if set)
365+
// Build context resolver - add extra context BEFORE processing blocks
366+
// so that templates like {{ workspace.root }} can resolve during block processing
357367
let mut context_resolver = match &self.parent_context {
358-
Some(parent) => {
359-
ContextResolver::from_blocks_with_parent(&self.blocks[..position], parent)
360-
}
361-
None => ContextResolver::from_blocks(&self.blocks[..position]),
368+
Some(parent) => ContextResolver::from_parent(parent),
369+
None => ContextResolver::new(),
362370
};
363-
if let Some(extra_template_context) = extra_template_context {
364-
for (namespace, context) in extra_template_context {
365-
context_resolver.add_extra_template_context(namespace.clone(), context.clone());
366-
}
367-
}
368371

369-
// Add workspace template context if available
372+
// Add workspace template context first (before blocks are processed)
370373
if let Some(ref workspace_root) = self.workspace_root {
371374
let mut workspace_context = HashMap::new();
372375
workspace_context.insert("root".to_string(), workspace_root.clone());
373376
context_resolver.add_extra_template_context("workspace".to_string(), workspace_context);
374377
}
375378

379+
// Add any extra template context passed by caller
380+
if let Some(extra_template_context) = extra_template_context {
381+
for (namespace, context) in extra_template_context {
382+
context_resolver.add_extra_template_context(namespace.clone(), context.clone());
383+
}
384+
}
385+
376386
let mut runbook_template_context = HashMap::new();
377387
runbook_template_context.insert("id".to_string(), self.id.clone());
378388
context_resolver
379389
.add_extra_template_context("runbook".to_string(), runbook_template_context);
380390

391+
// Now process blocks - templates will resolve against the context we just set up
392+
context_resolver.push_blocks(&self.blocks[..position]);
393+
381394
let block_outputs = self
382395
.blocks
383396
.iter()
@@ -423,12 +436,18 @@ impl Document {
423436
.get_block_index(block_id)
424437
.ok_or(DocumentError::BlockNotFound(*block_id))?;
425438

426-
let resolver = match &self.parent_context {
427-
Some(parent) => {
428-
ContextResolver::from_blocks_with_parent(&self.blocks[..position], parent)
429-
}
430-
None => ContextResolver::from_blocks(&self.blocks[..position]),
439+
let mut resolver = match &self.parent_context {
440+
Some(parent) => ContextResolver::from_parent(parent),
441+
None => ContextResolver::new(),
431442
};
443+
444+
if let Some(ref workspace_root) = self.workspace_root {
445+
let mut workspace_context = HashMap::new();
446+
workspace_context.insert("root".to_string(), workspace_root.clone());
447+
resolver.add_extra_template_context("workspace".to_string(), workspace_context);
448+
}
449+
450+
resolver.push_blocks(&self.blocks[..position]);
432451
Ok(ResolvedContext::from_resolver(&resolver))
433452
}
434453

@@ -462,18 +481,23 @@ impl Document {
462481
let mut errors = Vec::new();
463482
let start = start_index.unwrap_or(0);
464483

484+
// Build context resolver - add extra context BEFORE processing blocks
485+
// so that templates like {{ workspace.root }} can resolve during block processing
465486
let mut context_resolver = match &self.parent_context {
466-
Some(parent) => ContextResolver::from_blocks_with_parent(&self.blocks[..start], parent),
467-
None => ContextResolver::from_blocks(&self.blocks[..start]),
487+
Some(parent) => ContextResolver::from_parent(parent),
488+
None => ContextResolver::new(),
468489
};
469490

470-
// Add workspace template context if available
491+
// Add workspace template context first (before blocks are processed)
471492
if let Some(ref workspace_root) = self.workspace_root {
472493
let mut workspace_context = HashMap::new();
473494
workspace_context.insert("root".to_string(), workspace_root.clone());
474495
context_resolver.add_extra_template_context("workspace".to_string(), workspace_context);
475496
}
476497

498+
// Now process blocks[..start] with workspace context available
499+
context_resolver.push_blocks(&self.blocks[..start]);
500+
477501
for i in start..self.blocks.len() {
478502
let block_id = self.blocks[i].id();
479503

0 commit comments

Comments
 (0)