From f08bb70ee14d94e3bf8633732ed12134206d2f85 Mon Sep 17 00:00:00 2001 From: Casey Rodarmor Date: Tue, 30 Jul 2024 18:27:15 -0700 Subject: [PATCH 1/9] Fix backtick and `shell()` working directory in submodules --- src/analyzer.rs | 4 +++- src/ast.rs | 2 ++ src/evaluator.rs | 13 ++----------- src/execution_context.rs | 17 +++++++++++++++++ src/justfile.rs | 5 +++++ src/parser.rs | 3 ++- src/recipe.rs | 16 +++------------- 7 files changed, 34 insertions(+), 26 deletions(-) diff --git a/src/analyzer.rs b/src/analyzer.rs index 661e70922e..d09c62dc3f 100644 --- a/src/analyzer.rs +++ b/src/analyzer.rs @@ -35,7 +35,8 @@ impl<'src> Analyzer<'src> { let mut assignments = Vec::new(); let mut stack = Vec::new(); - stack.push(asts.get(root).unwrap()); + let root_ast = asts.get(root).unwrap(); + stack.push(root_ast); let mut warnings = Vec::new(); @@ -232,6 +233,7 @@ impl<'src> Analyzer<'src> { unexports, unstable_features, warnings, + working_directory: root_ast.working_directory.clone(), }) } diff --git a/src/ast.rs b/src/ast.rs index f2e01228c0..d927dd7d6c 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -9,6 +9,8 @@ pub(crate) struct Ast<'src> { pub(crate) items: Vec>, /// Non-fatal warnings encountered during parsing pub(crate) warnings: Vec, + + pub(crate) working_directory: PathBuf, } impl<'src> Display for Ast<'src> { diff --git a/src/evaluator.rs b/src/evaluator.rs index 191b7120fa..723e16b89a 100644 --- a/src/evaluator.rs +++ b/src/evaluator.rs @@ -22,6 +22,7 @@ impl<'src, 'run> Evaluator<'src, 'run> { let context = ExecutionContext { config, dotenv, + module, module_source: &module.source, scope: parent, search, @@ -239,17 +240,7 @@ impl<'src, 'run> Evaluator<'src, 'run> { let mut cmd = self.context.settings.shell_command(self.context.config); cmd.arg(command); cmd.args(args); - if let Some(working_directory) = &self.context.settings.working_directory { - cmd.current_dir( - self - .context - .search - .working_directory - .join(working_directory), - ) - } else { - cmd.current_dir(&self.context.search.working_directory) - }; + cmd.current_dir(self.context.working_directory()); cmd.export( self.context.settings, self.context.dotenv, diff --git a/src/execution_context.rs b/src/execution_context.rs index 2efd9e5b83..94647a3e36 100644 --- a/src/execution_context.rs +++ b/src/execution_context.rs @@ -4,9 +4,26 @@ use super::*; pub(crate) struct ExecutionContext<'src: 'run, 'run> { pub(crate) config: &'run Config, pub(crate) dotenv: &'run BTreeMap, + pub(crate) module: &'run Justfile<'src>, pub(crate) module_source: &'run Path, pub(crate) scope: &'run Scope<'src, 'run>, pub(crate) search: &'run Search, pub(crate) settings: &'run Settings<'src>, pub(crate) unexports: &'run HashSet, } + +impl<'src: 'run, 'run> ExecutionContext<'src, 'run> { + pub(crate) fn working_directory(&self) -> PathBuf { + let base = if self.module.name.is_some() { + &self.module.working_directory + } else { + &self.search.working_directory + }; + + if let Some(setting) = &self.settings.working_directory { + base.join(setting) + } else { + base.into() + } + } +} diff --git a/src/justfile.rs b/src/justfile.rs index ab8ee547f0..1b175d8dad 100644 --- a/src/justfile.rs +++ b/src/justfile.rs @@ -7,6 +7,7 @@ struct Invocation<'src: 'run, 'run> { recipe: &'run Recipe<'src>, scope: &'run Scope<'src, 'run>, settings: &'run Settings<'src>, + module: &'run Justfile<'src>, } #[derive(Debug, PartialEq, Serialize)] @@ -30,6 +31,8 @@ pub(crate) struct Justfile<'src> { #[serde(skip)] pub(crate) unstable_features: BTreeSet, pub(crate) warnings: Vec, + #[serde(skip)] + pub(crate) working_directory: PathBuf, } impl<'src> Justfile<'src> { @@ -204,6 +207,7 @@ impl<'src> Justfile<'src> { let context = ExecutionContext { config, dotenv: &dotenv, + module: invocation.module, module_source: invocation.module_source, scope: invocation.scope, search, @@ -272,6 +276,7 @@ impl<'src> Justfile<'src> { arguments: arguments.into(), settings: &self.settings, scope: parent, + module: self, }) } else { let module = self.modules.get(&path[position]).unwrap(); diff --git a/src/parser.rs b/src/parser.rs index a7b6243e0b..4b30bd1f53 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -446,8 +446,9 @@ impl<'run, 'src> Parser<'run, 'src> { if self.next_token == self.tokens.len() { Ok(Ast { - warnings: Vec::new(), items, + warnings: Vec::new(), + working_directory: self.working_directory.into(), }) } else { Err(self.internal_error(format!( diff --git a/src/recipe.rs b/src/recipe.rs index 0d40307e8a..4a3361597a 100644 --- a/src/recipe.rs +++ b/src/recipe.rs @@ -137,20 +137,10 @@ impl<'src, D> Recipe<'src, D> { } fn working_directory<'a>(&'a self, context: &'a ExecutionContext) -> Option { - if !self.change_directory() { - return None; - } - - let base = if self.submodule_depth > 0 { - &self.working_directory - } else { - &context.search.working_directory - }; - - if let Some(setting) = &context.settings.working_directory { - Some(base.join(setting)) + if self.change_directory() { + Some(context.working_directory()) } else { - Some(base.into()) + None } } From a43ae587cc4c61986c19e5e4891122eac596e6c3 Mon Sep 17 00:00:00 2001 From: Casey Rodarmor Date: Tue, 30 Jul 2024 18:33:32 -0700 Subject: [PATCH 2/9] Enhance --- src/evaluator.rs | 13 +++++++------ src/execution_context.rs | 5 +---- src/function.rs | 9 +++++---- src/justfile.rs | 13 +++---------- src/recipe.rs | 30 ++++++++++++++++++++---------- 5 files changed, 36 insertions(+), 34 deletions(-) diff --git a/src/evaluator.rs b/src/evaluator.rs index 723e16b89a..9efe807dc6 100644 --- a/src/evaluator.rs +++ b/src/evaluator.rs @@ -23,11 +23,8 @@ impl<'src, 'run> Evaluator<'src, 'run> { config, dotenv, module, - module_source: &module.source, scope: parent, search, - settings: &module.settings, - unexports: &module.unexports, }; let mut scope = context.scope.child(); @@ -237,15 +234,19 @@ impl<'src, 'run> Evaluator<'src, 'run> { } pub(crate) fn run_command(&self, command: &str, args: &[&str]) -> Result { - let mut cmd = self.context.settings.shell_command(self.context.config); + let mut cmd = self + .context + .module + .settings + .shell_command(self.context.config); cmd.arg(command); cmd.args(args); cmd.current_dir(self.context.working_directory()); cmd.export( - self.context.settings, + &self.context.module.settings, self.context.dotenv, &self.scope, - self.context.unexports, + &self.context.module.unexports, ); cmd.stdin(Stdio::inherit()); cmd.stderr(if self.context.config.verbosity.quiet() { diff --git a/src/execution_context.rs b/src/execution_context.rs index 94647a3e36..fa75ce752e 100644 --- a/src/execution_context.rs +++ b/src/execution_context.rs @@ -5,11 +5,8 @@ pub(crate) struct ExecutionContext<'src: 'run, 'run> { pub(crate) config: &'run Config, pub(crate) dotenv: &'run BTreeMap, pub(crate) module: &'run Justfile<'src>, - pub(crate) module_source: &'run Path, pub(crate) scope: &'run Scope<'src, 'run>, pub(crate) search: &'run Search, - pub(crate) settings: &'run Settings<'src>, - pub(crate) unexports: &'run HashSet, } impl<'src: 'run, 'run> ExecutionContext<'src, 'run> { @@ -20,7 +17,7 @@ impl<'src: 'run, 'run> ExecutionContext<'src, 'run> { &self.search.working_directory }; - if let Some(setting) = &self.settings.working_directory { + if let Some(setting) = &self.module.settings.working_directory { base.join(setting) } else { base.into() diff --git a/src/function.rs b/src/function.rs index 50bee73e08..013af683f8 100644 --- a/src/function.rs +++ b/src/function.rs @@ -458,7 +458,7 @@ fn module_directory(context: Context) -> FunctionResult { .justfile .parent() .unwrap() - .join(context.evaluator.context.module_source) + .join(&context.evaluator.context.module.source) .parent() .unwrap() .to_str() @@ -469,7 +469,8 @@ fn module_directory(context: Context) -> FunctionResult { context .evaluator .context - .module_source + .module + .source .parent() .unwrap() .display(), @@ -485,13 +486,13 @@ fn module_file(context: Context) -> FunctionResult { .justfile .parent() .unwrap() - .join(context.evaluator.context.module_source) + .join(&context.evaluator.context.module.source) .to_str() .map(str::to_owned) .ok_or_else(|| { format!( "Module file path is not valid unicode: {}", - context.evaluator.context.module_source.display(), + context.evaluator.context.module.source.display(), ) }) } diff --git a/src/justfile.rs b/src/justfile.rs index 1b175d8dad..c41254ff0e 100644 --- a/src/justfile.rs +++ b/src/justfile.rs @@ -3,11 +3,9 @@ use {super::*, serde::Serialize}; #[derive(Debug)] struct Invocation<'src: 'run, 'run> { arguments: Vec<&'run str>, - module_source: &'run Path, + module: &'run Justfile<'src>, recipe: &'run Recipe<'src>, scope: &'run Scope<'src, 'run>, - settings: &'run Settings<'src>, - module: &'run Justfile<'src>, } #[derive(Debug, PartialEq, Serialize)] @@ -208,11 +206,8 @@ impl<'src> Justfile<'src> { config, dotenv: &dotenv, module: invocation.module, - module_source: invocation.module_source, scope: invocation.scope, search, - settings: invocation.settings, - unexports: &self.unexports, }; Self::run_recipe( @@ -271,12 +266,10 @@ impl<'src> Justfile<'src> { if position + 1 == path.len() { let recipe = self.get_recipe(&path[position]).unwrap(); Ok(Invocation { - recipe, - module_source: &self.source, arguments: arguments.into(), - settings: &self.settings, - scope: parent, module: self, + recipe, + scope: parent, }) } else { let module = self.modules.get(&path[position]).unwrap(); diff --git a/src/recipe.rs b/src/recipe.rs index 4a3361597a..665979c6bf 100644 --- a/src/recipe.rs +++ b/src/recipe.rs @@ -195,8 +195,8 @@ impl<'src, D> Recipe<'src, D> { let quiet_line = lines.peek().map_or(false, |line| line.is_quiet()); let infallible_line = lines.peek().map_or(false, |line| line.is_infallible()); - let comment_line = - context.settings.ignore_comments && lines.peek().map_or(false, |line| line.is_comment()); + let comment_line = context.module.settings.ignore_comments + && lines.peek().map_or(false, |line| line.is_comment()); loop { if lines.peek().is_none() { @@ -232,7 +232,7 @@ impl<'src, D> Recipe<'src, D> { if config.dry_run || config.verbosity.loquacious() || !((quiet_line ^ self.quiet) - || (context.settings.quiet && !self.no_quiet()) + || (context.module.settings.quiet && !self.no_quiet()) || config.verbosity.quiet()) { let color = config @@ -259,7 +259,7 @@ impl<'src, D> Recipe<'src, D> { continue; } - let mut cmd = context.settings.shell_command(config); + let mut cmd = context.module.settings.shell_command(config); if let Some(working_directory) = self.working_directory(context) { cmd.current_dir(working_directory); @@ -267,7 +267,7 @@ impl<'src, D> Recipe<'src, D> { cmd.arg(command); - if self.takes_positional_arguments(context.settings) { + if self.takes_positional_arguments(&context.module.settings) { cmd.arg(self.name.lexeme()); cmd.args(positional); } @@ -277,7 +277,12 @@ impl<'src, D> Recipe<'src, D> { cmd.stdout(Stdio::null()); } - cmd.export(context.settings, context.dotenv, scope, context.unexports); + cmd.export( + &context.module.settings, + context.dotenv, + scope, + &context.module.unexports, + ); match InterruptHandler::guard(|| cmd.status()) { Ok(exit_status) => { @@ -346,7 +351,7 @@ impl<'src, D> Recipe<'src, D> { Executor::Command( interpreter .as_ref() - .or(context.settings.script_interpreter.as_ref()) + .or(context.module.settings.script_interpreter.as_ref()) .unwrap_or_else(|| Interpreter::default_script_interpreter()), ) } else { @@ -362,7 +367,7 @@ impl<'src, D> Recipe<'src, D> { let mut tempdir_builder = tempfile::Builder::new(); tempdir_builder.prefix("just-"); - let tempdir = match &context.settings.tempdir { + let tempdir = match &context.module.settings.tempdir { Some(tempdir) => tempdir_builder.tempdir_in(context.search.working_directory.join(tempdir)), None => { if let Some(runtime_dir) = dirs::runtime_dir() { @@ -410,11 +415,16 @@ impl<'src, D> Recipe<'src, D> { self.working_directory(context).as_deref(), )?; - if self.takes_positional_arguments(context.settings) { + if self.takes_positional_arguments(&context.module.settings) { command.args(positional); } - command.export(context.settings, context.dotenv, scope, context.unexports); + command.export( + &context.module.settings, + context.dotenv, + scope, + &context.module.unexports, + ); // run it! match InterruptHandler::guard(|| command.status()) { From 2dcb4c88f851b51dde4f8f6bcaeacc0416b216dd Mon Sep 17 00:00:00 2001 From: Casey Rodarmor Date: Tue, 30 Jul 2024 18:34:16 -0700 Subject: [PATCH 3/9] Reform --- src/analyzer.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/analyzer.rs b/src/analyzer.rs index d09c62dc3f..65bd382c31 100644 --- a/src/analyzer.rs +++ b/src/analyzer.rs @@ -35,8 +35,8 @@ impl<'src> Analyzer<'src> { let mut assignments = Vec::new(); let mut stack = Vec::new(); - let root_ast = asts.get(root).unwrap(); - stack.push(root_ast); + let ast = asts.get(root).unwrap(); + stack.push(ast); let mut warnings = Vec::new(); @@ -233,7 +233,7 @@ impl<'src> Analyzer<'src> { unexports, unstable_features, warnings, - working_directory: root_ast.working_directory.clone(), + working_directory: ast.working_directory.clone(), }) } From d477ccc23c226147e32841da2aa13a347a21a3a2 Mon Sep 17 00:00:00 2001 From: Casey Rodarmor Date: Tue, 30 Jul 2024 18:36:43 -0700 Subject: [PATCH 4/9] Modify --- src/compiler.rs | 2 -- src/parser.rs | 6 ------ src/recipe.rs | 2 -- src/testing.rs | 1 - src/unresolved_recipe.rs | 1 - 5 files changed, 12 deletions(-) diff --git a/src/compiler.rs b/src/compiler.rs index 322b1d200e..1a555ebabb 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -24,7 +24,6 @@ impl Compiler { ¤t.path, ¤t.import_offsets, ¤t.namepath, - current.submodule_depth, &tokens, ¤t.working_directory, )?; @@ -220,7 +219,6 @@ impl Compiler { &PathBuf::new(), &[], &Namepath::default(), - 0, &tokens, &PathBuf::new(), )?; diff --git a/src/parser.rs b/src/parser.rs index 4b30bd1f53..c5ca90c658 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -31,7 +31,6 @@ pub(crate) struct Parser<'run, 'src> { module_namepath: &'run Namepath<'src>, next_token: usize, recursion_depth: usize, - submodule_depth: u32, tokens: &'run [Token<'src>], working_directory: &'run Path, } @@ -43,7 +42,6 @@ impl<'run, 'src> Parser<'run, 'src> { file_path: &'run Path, import_offsets: &[usize], module_namepath: &'run Namepath<'src>, - submodule_depth: u32, tokens: &'run [Token<'src>], working_directory: &'run Path, ) -> CompileResult<'src, Ast<'src>> { @@ -55,7 +53,6 @@ impl<'run, 'src> Parser<'run, 'src> { module_namepath, next_token: 0, recursion_depth: 0, - submodule_depth, tokens, working_directory, } @@ -839,7 +836,6 @@ impl<'run, 'src> Parser<'run, 'src> { priors, private: name.lexeme().starts_with('_'), quiet, - submodule_depth: self.submodule_depth, working_directory: self.working_directory.into(), }) } @@ -1090,7 +1086,6 @@ mod tests { &PathBuf::new(), &[], &Namepath::default(), - 0, &tokens, &PathBuf::new(), ) @@ -1137,7 +1132,6 @@ mod tests { &PathBuf::new(), &[], &Namepath::default(), - 0, &tokens, &PathBuf::new(), ) { diff --git a/src/recipe.rs b/src/recipe.rs index 665979c6bf..5f671780c4 100644 --- a/src/recipe.rs +++ b/src/recipe.rs @@ -37,8 +37,6 @@ pub(crate) struct Recipe<'src, D = Dependency<'src>> { pub(crate) quiet: bool, pub(crate) shebang: bool, #[serde(skip)] - pub(crate) submodule_depth: u32, - #[serde(skip)] pub(crate) working_directory: PathBuf, } diff --git a/src/testing.rs b/src/testing.rs index a43262f10b..a10c398834 100644 --- a/src/testing.rs +++ b/src/testing.rs @@ -64,7 +64,6 @@ pub(crate) fn analysis_error( &PathBuf::new(), &[], &Namepath::default(), - 0, &tokens, &PathBuf::new(), ) diff --git a/src/unresolved_recipe.rs b/src/unresolved_recipe.rs index af076f2058..a0fa808d64 100644 --- a/src/unresolved_recipe.rs +++ b/src/unresolved_recipe.rs @@ -59,7 +59,6 @@ impl<'src> UnresolvedRecipe<'src> { private: self.private, quiet: self.quiet, shebang: self.shebang, - submodule_depth: self.submodule_depth, working_directory: self.working_directory, }) } From 31cc872e4e9d11f9b80335540c6cae096d39b735 Mon Sep 17 00:00:00 2001 From: Casey Rodarmor Date: Tue, 30 Jul 2024 18:38:25 -0700 Subject: [PATCH 5/9] Enhance --- src/execution_context.rs | 2 +- src/justfile.rs | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/execution_context.rs b/src/execution_context.rs index fa75ce752e..bd39ecfcd3 100644 --- a/src/execution_context.rs +++ b/src/execution_context.rs @@ -11,7 +11,7 @@ pub(crate) struct ExecutionContext<'src: 'run, 'run> { impl<'src: 'run, 'run> ExecutionContext<'src, 'run> { pub(crate) fn working_directory(&self) -> PathBuf { - let base = if self.module.name.is_some() { + let base = if self.module.is_submodule() { &self.module.working_directory } else { &self.search.working_directory diff --git a/src/justfile.rs b/src/justfile.rs index c41254ff0e..b31084ef18 100644 --- a/src/justfile.rs +++ b/src/justfile.rs @@ -304,6 +304,10 @@ impl<'src> Justfile<'src> { } } + pub(crate) fn is_submodule(&self) -> bool { + self.name.is_some() + } + pub(crate) fn name(&self) -> &'src str { self.name.map(|name| name.lexeme()).unwrap_or_default() } From 00100e1960d1489f48bdb4775eea451a3c743259 Mon Sep 17 00:00:00 2001 From: Casey Rodarmor Date: Tue, 30 Jul 2024 18:39:52 -0700 Subject: [PATCH 6/9] Revise --- src/source.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/source.rs b/src/source.rs index f81ae0ba22..5b125ecc35 100644 --- a/src/source.rs +++ b/src/source.rs @@ -7,7 +7,6 @@ pub(crate) struct Source<'src> { pub(crate) import_offsets: Vec, pub(crate) namepath: Namepath<'src>, pub(crate) path: PathBuf, - pub(crate) submodule_depth: u32, pub(crate) working_directory: PathBuf, } @@ -19,7 +18,6 @@ impl<'src> Source<'src> { import_offsets: Vec::new(), namepath: Namepath::default(), path: path.into(), - submodule_depth: 0, working_directory: path.parent().unwrap().into(), } } @@ -41,7 +39,6 @@ impl<'src> Source<'src> { .collect(), namepath: self.namepath.clone(), path, - submodule_depth: self.submodule_depth, working_directory: self.working_directory.clone(), } } @@ -58,7 +55,6 @@ impl<'src> Source<'src> { import_offsets: Vec::new(), namepath: self.namepath.join(name), path: path.clone(), - submodule_depth: self.submodule_depth + 1, working_directory: path.parent().unwrap().into(), } } From 6316985053da87d3d5ab8d2dd1fa361a02bd393a Mon Sep 17 00:00:00 2001 From: Casey Rodarmor Date: Tue, 30 Jul 2024 18:40:50 -0700 Subject: [PATCH 7/9] Amend --- src/ast.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/ast.rs b/src/ast.rs index d927dd7d6c..f9dd10c9f3 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -5,11 +5,8 @@ use super::*; /// are performed by the `Analyzer`, which produces a `Justfile` from an `Ast`. #[derive(Debug, Clone)] pub(crate) struct Ast<'src> { - /// Items in the justfile pub(crate) items: Vec>, - /// Non-fatal warnings encountered during parsing pub(crate) warnings: Vec, - pub(crate) working_directory: PathBuf, } From 680ea69a6294f934a680b794aabc72172944158f Mon Sep 17 00:00:00 2001 From: Casey Rodarmor Date: Tue, 30 Jul 2024 18:43:19 -0700 Subject: [PATCH 8/9] Revise --- src/parser.rs | 1 - src/recipe.rs | 2 -- src/unresolved_recipe.rs | 1 - 3 files changed, 4 deletions(-) diff --git a/src/parser.rs b/src/parser.rs index c5ca90c658..adc95048e7 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -836,7 +836,6 @@ impl<'run, 'src> Parser<'run, 'src> { priors, private: name.lexeme().starts_with('_'), quiet, - working_directory: self.working_directory.into(), }) } diff --git a/src/recipe.rs b/src/recipe.rs index 5f671780c4..78b3ef27fa 100644 --- a/src/recipe.rs +++ b/src/recipe.rs @@ -36,8 +36,6 @@ pub(crate) struct Recipe<'src, D = Dependency<'src>> { pub(crate) private: bool, pub(crate) quiet: bool, pub(crate) shebang: bool, - #[serde(skip)] - pub(crate) working_directory: PathBuf, } impl<'src, D> Recipe<'src, D> { diff --git a/src/unresolved_recipe.rs b/src/unresolved_recipe.rs index a0fa808d64..6cbc95da91 100644 --- a/src/unresolved_recipe.rs +++ b/src/unresolved_recipe.rs @@ -59,7 +59,6 @@ impl<'src> UnresolvedRecipe<'src> { private: self.private, quiet: self.quiet, shebang: self.shebang, - working_directory: self.working_directory, }) } } From d9b058ccb566c24364ba52c2d64c0b020f8681ed Mon Sep 17 00:00:00 2001 From: Casey Rodarmor Date: Tue, 30 Jul 2024 18:48:34 -0700 Subject: [PATCH 9/9] Adjust --- tests/working_directory.rs | 60 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/tests/working_directory.rs b/tests/working_directory.rs index eb6618c6ec..3396b73eb7 100644 --- a/tests/working_directory.rs +++ b/tests/working_directory.rs @@ -271,3 +271,63 @@ fn working_dir_applies_to_backticks() { .stdout("FILE\n") .run(); } + +#[test] +fn working_dir_applies_to_shell_function() { + Test::new() + .justfile( + " + set working-directory := 'foo' + + file := shell('cat file.txt') + + @foo: + echo {{ file }} + ", + ) + .write("foo/file.txt", "FILE") + .stdout("FILE\n") + .run(); +} + +#[test] +fn working_dir_applies_to_backticks_in_submodules() { + Test::new() + .justfile("mod foo") + .write( + "foo/mod.just", + " +set working-directory := 'bar' + +file := `cat file.txt` + +@foo: + echo {{ file }} +", + ) + .arg("foo") + .write("foo/bar/file.txt", "FILE") + .stdout("FILE\n") + .run(); +} + +#[test] +fn working_dir_applies_to_shell_function_in_submodules() { + Test::new() + .justfile("mod foo") + .write( + "foo/mod.just", + " +set working-directory := 'bar' + +file := shell('cat file.txt') + +@foo: + echo {{ file }} +", + ) + .arg("foo") + .write("foo/bar/file.txt", "FILE") + .stdout("FILE\n") + .run(); +}