Run imported recipes in root justfile with correct working directory (#2056)
This commit is contained in:
parent
b1c7491486
commit
104608d8cc
@ -133,7 +133,7 @@ impl<'src> Analyzer<'src> {
|
||||
define(recipe.name, "recipe", settings.allow_duplicate_recipes)?;
|
||||
if recipe_table
|
||||
.get(recipe.name.lexeme())
|
||||
.map_or(true, |original| recipe.depth <= original.depth)
|
||||
.map_or(true, |original| recipe.file_depth <= original.file_depth)
|
||||
{
|
||||
recipe_table.insert(recipe.clone());
|
||||
}
|
||||
|
@ -21,9 +21,10 @@ impl Compiler {
|
||||
loaded.push(relative.into());
|
||||
let tokens = Lexer::lex(relative, src)?;
|
||||
let mut ast = Parser::parse(
|
||||
current.file_depth,
|
||||
¤t.path,
|
||||
¤t.namepath,
|
||||
current.depth,
|
||||
current.submodule_depth,
|
||||
&tokens,
|
||||
¤t.working_directory,
|
||||
)?;
|
||||
@ -169,6 +170,7 @@ impl Compiler {
|
||||
pub(crate) fn test_compile(src: &str) -> CompileResult<Justfile> {
|
||||
let tokens = Lexer::test_lex(src)?;
|
||||
let ast = Parser::parse(
|
||||
0,
|
||||
&PathBuf::new(),
|
||||
&Namepath::default(),
|
||||
0,
|
||||
|
@ -25,6 +25,7 @@ use {super::*, TokenKind::*};
|
||||
/// contents of the set is printed in the resultant error message.
|
||||
pub(crate) struct Parser<'run, 'src> {
|
||||
expected_tokens: BTreeSet<TokenKind>,
|
||||
file_depth: u32,
|
||||
file_path: &'run Path,
|
||||
module_namepath: &'run Namepath<'src>,
|
||||
next_token: usize,
|
||||
@ -37,6 +38,7 @@ pub(crate) struct Parser<'run, 'src> {
|
||||
impl<'run, 'src> Parser<'run, 'src> {
|
||||
/// Parse `tokens` into an `Ast`
|
||||
pub(crate) fn parse(
|
||||
file_depth: u32,
|
||||
file_path: &'run Path,
|
||||
module_namepath: &'run Namepath<'src>,
|
||||
submodule_depth: u32,
|
||||
@ -45,6 +47,7 @@ impl<'run, 'src> Parser<'run, 'src> {
|
||||
) -> CompileResult<'src, Ast<'src>> {
|
||||
Self {
|
||||
expected_tokens: BTreeSet::new(),
|
||||
file_depth,
|
||||
file_path,
|
||||
module_namepath,
|
||||
next_token: 0,
|
||||
@ -456,7 +459,7 @@ impl<'run, 'src> Parser<'run, 'src> {
|
||||
let value = self.parse_expression()?;
|
||||
self.expect_eol()?;
|
||||
Ok(Assignment {
|
||||
depth: self.submodule_depth,
|
||||
depth: self.file_depth,
|
||||
export,
|
||||
name,
|
||||
value,
|
||||
@ -769,8 +772,8 @@ impl<'run, 'src> Parser<'run, 'src> {
|
||||
attributes,
|
||||
body,
|
||||
dependencies,
|
||||
depth: self.submodule_depth,
|
||||
doc,
|
||||
file_depth: self.file_depth,
|
||||
file_path: self.file_path.into(),
|
||||
name,
|
||||
namepath: self.module_namepath.join(name),
|
||||
@ -778,6 +781,7 @@ impl<'run, 'src> Parser<'run, 'src> {
|
||||
priors,
|
||||
private: name.lexeme().starts_with('_'),
|
||||
quiet,
|
||||
submodule_depth: self.submodule_depth,
|
||||
working_directory: self.working_directory.into(),
|
||||
})
|
||||
}
|
||||
@ -1010,6 +1014,7 @@ mod tests {
|
||||
let unindented = unindent(text);
|
||||
let tokens = Lexer::test_lex(&unindented).expect("lexing failed");
|
||||
let justfile = Parser::parse(
|
||||
0,
|
||||
&PathBuf::new(),
|
||||
&Namepath::default(),
|
||||
0,
|
||||
@ -1055,6 +1060,7 @@ mod tests {
|
||||
let tokens = Lexer::test_lex(src).expect("Lexing failed in parse test...");
|
||||
|
||||
match Parser::parse(
|
||||
0,
|
||||
&PathBuf::new(),
|
||||
&Namepath::default(),
|
||||
0,
|
||||
|
@ -22,10 +22,10 @@ pub(crate) struct Recipe<'src, D = Dependency<'src>> {
|
||||
pub(crate) attributes: BTreeSet<Attribute<'src>>,
|
||||
pub(crate) body: Vec<Line<'src>>,
|
||||
pub(crate) dependencies: Vec<D>,
|
||||
#[serde(skip)]
|
||||
pub(crate) depth: u32,
|
||||
pub(crate) doc: Option<&'src str>,
|
||||
#[serde(skip)]
|
||||
pub(crate) file_depth: u32,
|
||||
#[serde(skip)]
|
||||
pub(crate) file_path: PathBuf,
|
||||
pub(crate) name: Name<'src>,
|
||||
pub(crate) namepath: Namepath<'src>,
|
||||
@ -35,6 +35,8 @@ 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,
|
||||
}
|
||||
|
||||
@ -126,7 +128,7 @@ impl<'src, D> Recipe<'src, D> {
|
||||
|
||||
fn working_directory<'a>(&'a self, search: &'a Search) -> Option<&Path> {
|
||||
if self.change_directory() {
|
||||
Some(if self.depth > 0 {
|
||||
Some(if self.submodule_depth > 0 {
|
||||
&self.working_directory
|
||||
} else {
|
||||
&search.working_directory
|
||||
|
@ -1,37 +1,41 @@
|
||||
use super::*;
|
||||
|
||||
pub(crate) struct Source<'src> {
|
||||
pub(crate) path: PathBuf,
|
||||
pub(crate) depth: u32,
|
||||
pub(crate) file_depth: u32,
|
||||
pub(crate) namepath: Namepath<'src>,
|
||||
pub(crate) path: PathBuf,
|
||||
pub(crate) submodule_depth: u32,
|
||||
pub(crate) working_directory: PathBuf,
|
||||
}
|
||||
|
||||
impl<'src> Source<'src> {
|
||||
pub(crate) fn root(path: &Path) -> Self {
|
||||
Self {
|
||||
path: path.into(),
|
||||
depth: 0,
|
||||
file_depth: 0,
|
||||
namepath: Namepath::default(),
|
||||
path: path.into(),
|
||||
submodule_depth: 0,
|
||||
working_directory: path.parent().unwrap().into(),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn import(&self, path: PathBuf) -> Self {
|
||||
Self {
|
||||
depth: self.depth + 1,
|
||||
path,
|
||||
file_depth: self.file_depth + 1,
|
||||
namepath: self.namepath.clone(),
|
||||
path,
|
||||
submodule_depth: self.submodule_depth,
|
||||
working_directory: self.working_directory.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn module(&self, name: Name<'src>, path: PathBuf) -> Self {
|
||||
Self {
|
||||
file_depth: self.file_depth + 1,
|
||||
namepath: self.namepath.join(name),
|
||||
submodule_depth: self.submodule_depth + 1,
|
||||
working_directory: path.parent().unwrap().into(),
|
||||
path,
|
||||
depth: self.depth + 1,
|
||||
namepath: self.namepath.join(name),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -60,6 +60,7 @@ pub(crate) fn analysis_error(
|
||||
let tokens = Lexer::test_lex(src).expect("Lexing failed in parse test...");
|
||||
|
||||
let ast = Parser::parse(
|
||||
0,
|
||||
&PathBuf::new(),
|
||||
&Namepath::default(),
|
||||
0,
|
||||
|
@ -48,8 +48,8 @@ impl<'src> UnresolvedRecipe<'src> {
|
||||
attributes: self.attributes,
|
||||
body: self.body,
|
||||
dependencies,
|
||||
depth: self.depth,
|
||||
doc: self.doc,
|
||||
file_depth: self.file_depth,
|
||||
file_path: self.file_path,
|
||||
name: self.name,
|
||||
namepath: self.namepath,
|
||||
@ -58,6 +58,7 @@ impl<'src> UnresolvedRecipe<'src> {
|
||||
private: self.private,
|
||||
quiet: self.quiet,
|
||||
shebang: self.shebang,
|
||||
submodule_depth: self.submodule_depth,
|
||||
working_directory: self.working_directory,
|
||||
})
|
||||
}
|
||||
|
@ -344,3 +344,20 @@ fn shebang_recipes_in_imports_in_root_run_in_justfile_directory() {
|
||||
.stdout("BAZ")
|
||||
.run();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn recipes_imported_in_root_run_in_command_line_provided_working_directory() {
|
||||
Test::new()
|
||||
.write("subdir/b.justfile", "@b:\n cat baz")
|
||||
.write("subdir/a.justfile", "import 'b.justfile'\n@a: b\n cat baz")
|
||||
.write("baz", "BAZ")
|
||||
.args([
|
||||
"--working-directory",
|
||||
".",
|
||||
"--justfile",
|
||||
"subdir/a.justfile",
|
||||
])
|
||||
.test_round_trip(false)
|
||||
.stdout("BAZBAZ")
|
||||
.run();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user