Skip to content

Commit 104608d

Browse files
authored
Run imported recipes in root justfile with correct working directory (#2056)
1 parent b1c7491 commit 104608d

File tree

8 files changed

+49
-16
lines changed

8 files changed

+49
-16
lines changed

src/analyzer.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ impl<'src> Analyzer<'src> {
133133
define(recipe.name, "recipe", settings.allow_duplicate_recipes)?;
134134
if recipe_table
135135
.get(recipe.name.lexeme())
136-
.map_or(true, |original| recipe.depth <= original.depth)
136+
.map_or(true, |original| recipe.file_depth <= original.file_depth)
137137
{
138138
recipe_table.insert(recipe.clone());
139139
}

src/compiler.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,10 @@ impl Compiler {
2121
loaded.push(relative.into());
2222
let tokens = Lexer::lex(relative, src)?;
2323
let mut ast = Parser::parse(
24+
current.file_depth,
2425
&current.path,
2526
&current.namepath,
26-
current.depth,
27+
current.submodule_depth,
2728
&tokens,
2829
&current.working_directory,
2930
)?;
@@ -169,6 +170,7 @@ impl Compiler {
169170
pub(crate) fn test_compile(src: &str) -> CompileResult<Justfile> {
170171
let tokens = Lexer::test_lex(src)?;
171172
let ast = Parser::parse(
173+
0,
172174
&PathBuf::new(),
173175
&Namepath::default(),
174176
0,

src/parser.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ use {super::*, TokenKind::*};
2525
/// contents of the set is printed in the resultant error message.
2626
pub(crate) struct Parser<'run, 'src> {
2727
expected_tokens: BTreeSet<TokenKind>,
28+
file_depth: u32,
2829
file_path: &'run Path,
2930
module_namepath: &'run Namepath<'src>,
3031
next_token: usize,
@@ -37,6 +38,7 @@ pub(crate) struct Parser<'run, 'src> {
3738
impl<'run, 'src> Parser<'run, 'src> {
3839
/// Parse `tokens` into an `Ast`
3940
pub(crate) fn parse(
41+
file_depth: u32,
4042
file_path: &'run Path,
4143
module_namepath: &'run Namepath<'src>,
4244
submodule_depth: u32,
@@ -45,6 +47,7 @@ impl<'run, 'src> Parser<'run, 'src> {
4547
) -> CompileResult<'src, Ast<'src>> {
4648
Self {
4749
expected_tokens: BTreeSet::new(),
50+
file_depth,
4851
file_path,
4952
module_namepath,
5053
next_token: 0,
@@ -456,7 +459,7 @@ impl<'run, 'src> Parser<'run, 'src> {
456459
let value = self.parse_expression()?;
457460
self.expect_eol()?;
458461
Ok(Assignment {
459-
depth: self.submodule_depth,
462+
depth: self.file_depth,
460463
export,
461464
name,
462465
value,
@@ -769,15 +772,16 @@ impl<'run, 'src> Parser<'run, 'src> {
769772
attributes,
770773
body,
771774
dependencies,
772-
depth: self.submodule_depth,
773775
doc,
776+
file_depth: self.file_depth,
774777
file_path: self.file_path.into(),
775778
name,
776779
namepath: self.module_namepath.join(name),
777780
parameters: positional.into_iter().chain(variadic).collect(),
778781
priors,
779782
private: name.lexeme().starts_with('_'),
780783
quiet,
784+
submodule_depth: self.submodule_depth,
781785
working_directory: self.working_directory.into(),
782786
})
783787
}
@@ -1010,6 +1014,7 @@ mod tests {
10101014
let unindented = unindent(text);
10111015
let tokens = Lexer::test_lex(&unindented).expect("lexing failed");
10121016
let justfile = Parser::parse(
1017+
0,
10131018
&PathBuf::new(),
10141019
&Namepath::default(),
10151020
0,
@@ -1055,6 +1060,7 @@ mod tests {
10551060
let tokens = Lexer::test_lex(src).expect("Lexing failed in parse test...");
10561061

10571062
match Parser::parse(
1063+
0,
10581064
&PathBuf::new(),
10591065
&Namepath::default(),
10601066
0,

src/recipe.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@ pub(crate) struct Recipe<'src, D = Dependency<'src>> {
2222
pub(crate) attributes: BTreeSet<Attribute<'src>>,
2323
pub(crate) body: Vec<Line<'src>>,
2424
pub(crate) dependencies: Vec<D>,
25-
#[serde(skip)]
26-
pub(crate) depth: u32,
2725
pub(crate) doc: Option<&'src str>,
2826
#[serde(skip)]
27+
pub(crate) file_depth: u32,
28+
#[serde(skip)]
2929
pub(crate) file_path: PathBuf,
3030
pub(crate) name: Name<'src>,
3131
pub(crate) namepath: Namepath<'src>,
@@ -35,6 +35,8 @@ pub(crate) struct Recipe<'src, D = Dependency<'src>> {
3535
pub(crate) quiet: bool,
3636
pub(crate) shebang: bool,
3737
#[serde(skip)]
38+
pub(crate) submodule_depth: u32,
39+
#[serde(skip)]
3840
pub(crate) working_directory: PathBuf,
3941
}
4042

@@ -126,7 +128,7 @@ impl<'src, D> Recipe<'src, D> {
126128

127129
fn working_directory<'a>(&'a self, search: &'a Search) -> Option<&Path> {
128130
if self.change_directory() {
129-
Some(if self.depth > 0 {
131+
Some(if self.submodule_depth > 0 {
130132
&self.working_directory
131133
} else {
132134
&search.working_directory

src/source.rs

+12-8
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,41 @@
11
use super::*;
22

33
pub(crate) struct Source<'src> {
4-
pub(crate) path: PathBuf,
5-
pub(crate) depth: u32,
4+
pub(crate) file_depth: u32,
65
pub(crate) namepath: Namepath<'src>,
6+
pub(crate) path: PathBuf,
7+
pub(crate) submodule_depth: u32,
78
pub(crate) working_directory: PathBuf,
89
}
910

1011
impl<'src> Source<'src> {
1112
pub(crate) fn root(path: &Path) -> Self {
1213
Self {
13-
path: path.into(),
14-
depth: 0,
14+
file_depth: 0,
1515
namepath: Namepath::default(),
16+
path: path.into(),
17+
submodule_depth: 0,
1618
working_directory: path.parent().unwrap().into(),
1719
}
1820
}
1921

2022
pub(crate) fn import(&self, path: PathBuf) -> Self {
2123
Self {
22-
depth: self.depth + 1,
23-
path,
24+
file_depth: self.file_depth + 1,
2425
namepath: self.namepath.clone(),
26+
path,
27+
submodule_depth: self.submodule_depth,
2528
working_directory: self.working_directory.clone(),
2629
}
2730
}
2831

2932
pub(crate) fn module(&self, name: Name<'src>, path: PathBuf) -> Self {
3033
Self {
34+
file_depth: self.file_depth + 1,
35+
namepath: self.namepath.join(name),
36+
submodule_depth: self.submodule_depth + 1,
3137
working_directory: path.parent().unwrap().into(),
3238
path,
33-
depth: self.depth + 1,
34-
namepath: self.namepath.join(name),
3539
}
3640
}
3741
}

src/testing.rs

+1
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ pub(crate) fn analysis_error(
6060
let tokens = Lexer::test_lex(src).expect("Lexing failed in parse test...");
6161

6262
let ast = Parser::parse(
63+
0,
6364
&PathBuf::new(),
6465
&Namepath::default(),
6566
0,

src/unresolved_recipe.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ impl<'src> UnresolvedRecipe<'src> {
4848
attributes: self.attributes,
4949
body: self.body,
5050
dependencies,
51-
depth: self.depth,
5251
doc: self.doc,
52+
file_depth: self.file_depth,
5353
file_path: self.file_path,
5454
name: self.name,
5555
namepath: self.namepath,
@@ -58,6 +58,7 @@ impl<'src> UnresolvedRecipe<'src> {
5858
private: self.private,
5959
quiet: self.quiet,
6060
shebang: self.shebang,
61+
submodule_depth: self.submodule_depth,
6162
working_directory: self.working_directory,
6263
})
6364
}

tests/imports.rs

+17
Original file line numberDiff line numberDiff line change
@@ -344,3 +344,20 @@ fn shebang_recipes_in_imports_in_root_run_in_justfile_directory() {
344344
.stdout("BAZ")
345345
.run();
346346
}
347+
348+
#[test]
349+
fn recipes_imported_in_root_run_in_command_line_provided_working_directory() {
350+
Test::new()
351+
.write("subdir/b.justfile", "@b:\n cat baz")
352+
.write("subdir/a.justfile", "import 'b.justfile'\n@a: b\n cat baz")
353+
.write("baz", "BAZ")
354+
.args([
355+
"--working-directory",
356+
".",
357+
"--justfile",
358+
"subdir/a.justfile",
359+
])
360+
.test_round_trip(false)
361+
.stdout("BAZBAZ")
362+
.run();
363+
}

0 commit comments

Comments
 (0)