Skip to content

Commit 99f1c13

Browse files
committed
Support using env attribute in recipe params
1 parent 323502b commit 99f1c13

5 files changed

Lines changed: 45 additions & 9 deletions

File tree

src/evaluator.rs

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use super::*;
33
pub(crate) struct Evaluator<'src: 'run, 'run> {
44
assignments: Option<&'run Table<'src, Assignment<'src>>>,
55
context: Option<ExecutionContext<'src, 'run>>,
6+
env_vars: BTreeMap<String, String>,
67
is_dependency: bool,
78
non_const_assignments: Table<'src, Name<'src>>,
89
scope: Scope<'src, 'run>,
@@ -53,6 +54,7 @@ impl<'src, 'run> Evaluator<'src, 'run> {
5354
let mut evaluator = Self {
5455
assignments: Some(assignments),
5556
context: None,
57+
env_vars: BTreeMap::new(),
5658
is_dependency: false,
5759
non_const_assignments: Table::new(),
5860
scope,
@@ -201,6 +203,7 @@ impl<'src, 'run> Evaluator<'src, 'run> {
201203
let mut evaluator = Self {
202204
assignments: Some(&module.assignments),
203205
context: Some(context),
206+
env_vars: BTreeMap::new(),
204207
is_dependency: false,
205208
non_const_assignments: Table::new(),
206209
scope,
@@ -273,12 +276,12 @@ impl<'src, 'run> Evaluator<'src, 'run> {
273276
return Ok(format!("`{contents}`"));
274277
}
275278

276-
Self::run_command(context, &self.scope, contents, &[]).map_err(|output_error| {
277-
Error::Backtick {
279+
Self::run_command(context, &self.env_vars, &self.scope, contents, &[]).map_err(
280+
|output_error| Error::Backtick {
278281
token: *token,
279282
output_error,
280-
}
281-
})
283+
},
284+
)
282285
}
283286
Expression::Call { thunk } => {
284287
use Thunk::*;
@@ -436,6 +439,7 @@ impl<'src, 'run> Evaluator<'src, 'run> {
436439

437440
pub(crate) fn run_command(
438441
context: &ExecutionContext,
442+
env_vars: &BTreeMap<String, String>,
439443
scope: &Scope,
440444
command: &str,
441445
args: &[&str],
@@ -460,6 +464,10 @@ impl<'src, 'run> Evaluator<'src, 'run> {
460464
})
461465
.stdout(Stdio::piped());
462466

467+
for (key, value) in env_vars {
468+
cmd.env(key, value);
469+
}
470+
463471
cmd.output_guard_stdout()
464472
}
465473

@@ -498,7 +506,13 @@ impl<'src, 'run> Evaluator<'src, 'run> {
498506
recipe: &Recipe<'src>,
499507
scope: &'run Scope<'src, 'run>,
500508
) -> RunResult<'src, (Scope<'src, 'run>, Vec<String>)> {
501-
let mut evaluator = Self::new(context, is_dependency, scope);
509+
let mut env_vars = BTreeMap::new();
510+
for attribute in &recipe.attributes {
511+
if let Attribute::Env(key, value) = attribute {
512+
env_vars.insert(key.cooked.clone(), value.cooked.clone());
513+
}
514+
}
515+
let mut evaluator = Self::new(context, env_vars, is_dependency, scope);
502516

503517
let mut positional = Vec::new();
504518

@@ -550,12 +564,14 @@ impl<'src, 'run> Evaluator<'src, 'run> {
550564

551565
pub(crate) fn new(
552566
context: &ExecutionContext<'src, 'run>,
567+
env_vars: BTreeMap<String, String>,
553568
is_dependency: bool,
554569
scope: &'run Scope<'src, 'run>,
555570
) -> Self {
556571
Self {
557572
assignments: None,
558573
context: Some(*context),
574+
env_vars,
559575
is_dependency,
560576
non_const_assignments: Table::new(),
561577
scope: scope.child(),

src/function.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -544,8 +544,14 @@ fn shell(context: Context, command: &str, args: &[String]) -> FunctionResult {
544544
.chain(args.iter().map(String::as_str))
545545
.collect::<Vec<&str>>();
546546

547-
Evaluator::run_command(context.execution_context, context.scope, command, &args)
548-
.map_err(|output_error| output_error.to_string())
547+
Evaluator::run_command(
548+
context.execution_context,
549+
&BTreeMap::new(),
550+
context.scope,
551+
command,
552+
&args,
553+
)
554+
.map_err(|output_error| output_error.to_string())
549555
}
550556

551557
fn shoutykebabcase(_context: Context, s: &str) -> FunctionResult {

src/justfile.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ impl<'src> Justfile<'src> {
304304

305305
let scope = outer.child();
306306

307-
let mut evaluator = Evaluator::new(&context, true, &scope);
307+
let mut evaluator = Evaluator::new(&context, BTreeMap::new(), true, &scope);
308308

309309
Self::run_dependencies(
310310
config,

src/recipe.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ impl<'src, D> Recipe<'src, D> {
222222
}
223223
}
224224

225-
let evaluator = Evaluator::new(context, is_dependency, scope);
225+
let evaluator = Evaluator::new(context, BTreeMap::new(), is_dependency, scope);
226226

227227
if self.is_script() {
228228
self.run_script(context, scope, positional, evaluator)

tests/attributes.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,20 @@ fn env_attribute_multiple() {
342342
.run();
343343
}
344344

345+
#[test]
346+
fn env_attribute_in_recipe_params() {
347+
Test::new()
348+
.justfile(
349+
r#"
350+
[env("foo", "bar")]
351+
baz x=`echo ${foo}.txt`:
352+
@echo {{x}}
353+
"#,
354+
)
355+
.stdout("bar.txt\n")
356+
.run();
357+
}
358+
345359
#[test]
346360
fn env_attribute_too_few_arguments() {
347361
Test::new()

0 commit comments

Comments
 (0)