Allow mod statements with path to source file (#1786)
This commit is contained in:
parent
2846df7e27
commit
94b3af6cb7
@ -77,7 +77,7 @@ impl<'src> Analyzer<'src> {
|
|||||||
Item::Import { absolute, .. } => {
|
Item::Import { absolute, .. } => {
|
||||||
stack.push(asts.get(absolute.as_ref().unwrap()).unwrap());
|
stack.push(asts.get(absolute.as_ref().unwrap()).unwrap());
|
||||||
}
|
}
|
||||||
Item::Mod { absolute, name } => {
|
Item::Mod { absolute, name, .. } => {
|
||||||
define(*name, "module", false)?;
|
define(*name, "module", false)?;
|
||||||
modules.insert(
|
modules.insert(
|
||||||
name.to_string(),
|
name.to_string(),
|
||||||
|
@ -27,7 +27,11 @@ impl Compiler {
|
|||||||
|
|
||||||
for item in &mut ast.items {
|
for item in &mut ast.items {
|
||||||
match item {
|
match item {
|
||||||
Item::Mod { name, absolute } => {
|
Item::Mod {
|
||||||
|
name,
|
||||||
|
absolute,
|
||||||
|
path,
|
||||||
|
} => {
|
||||||
if !unstable {
|
if !unstable {
|
||||||
return Err(Error::Unstable {
|
return Err(Error::Unstable {
|
||||||
message: "Modules are currently unstable.".into(),
|
message: "Modules are currently unstable.".into(),
|
||||||
@ -36,7 +40,11 @@ impl Compiler {
|
|||||||
|
|
||||||
let parent = current.parent().unwrap();
|
let parent = current.parent().unwrap();
|
||||||
|
|
||||||
let import = Self::find_module_file(parent, *name)?;
|
let import = if let Some(path) = path {
|
||||||
|
parent.join(&path.cooked)
|
||||||
|
} else {
|
||||||
|
Self::find_module_file(parent, *name)?
|
||||||
|
};
|
||||||
|
|
||||||
if srcs.contains_key(&import) {
|
if srcs.contains_key(&import) {
|
||||||
return Err(Error::CircularImport { current, import });
|
return Err(Error::CircularImport { current, import });
|
||||||
|
11
src/item.rs
11
src/item.rs
@ -13,6 +13,7 @@ pub(crate) enum Item<'src> {
|
|||||||
Mod {
|
Mod {
|
||||||
name: Name<'src>,
|
name: Name<'src>,
|
||||||
absolute: Option<PathBuf>,
|
absolute: Option<PathBuf>,
|
||||||
|
path: Option<StringLiteral<'src>>,
|
||||||
},
|
},
|
||||||
Recipe(UnresolvedRecipe<'src>),
|
Recipe(UnresolvedRecipe<'src>),
|
||||||
Set(Set<'src>),
|
Set(Set<'src>),
|
||||||
@ -25,7 +26,15 @@ impl<'src> Display for Item<'src> {
|
|||||||
Item::Assignment(assignment) => write!(f, "{assignment}"),
|
Item::Assignment(assignment) => write!(f, "{assignment}"),
|
||||||
Item::Comment(comment) => write!(f, "{comment}"),
|
Item::Comment(comment) => write!(f, "{comment}"),
|
||||||
Item::Import { relative, .. } => write!(f, "import {relative}"),
|
Item::Import { relative, .. } => write!(f, "import {relative}"),
|
||||||
Item::Mod { name, .. } => write!(f, "mod {name}"),
|
Item::Mod { name, path, .. } => {
|
||||||
|
write!(f, "mod {name}")?;
|
||||||
|
|
||||||
|
if let Some(path) = path {
|
||||||
|
write!(f, " {path}")?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
Item::Recipe(recipe) => write!(f, "{}", recipe.color_display(Color::never())),
|
Item::Recipe(recipe) => write!(f, "{}", recipe.color_display(Color::never())),
|
||||||
Item::Set(set) => write!(f, "{set}"),
|
Item::Set(set) => write!(f, "{set}"),
|
||||||
}
|
}
|
||||||
|
@ -335,11 +335,24 @@ impl<'tokens, 'src> Parser<'tokens, 'src> {
|
|||||||
absolute: None,
|
absolute: None,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Some(Keyword::Mod) if self.next_are(&[Identifier, Identifier]) => {
|
Some(Keyword::Mod)
|
||||||
|
if self.next_are(&[Identifier, Identifier, StringToken])
|
||||||
|
|| self.next_are(&[Identifier, Identifier, Eof])
|
||||||
|
|| self.next_are(&[Identifier, Identifier, Eol]) =>
|
||||||
|
{
|
||||||
self.presume_keyword(Keyword::Mod)?;
|
self.presume_keyword(Keyword::Mod)?;
|
||||||
|
let name = self.parse_name()?;
|
||||||
|
|
||||||
|
let path = if self.next_is(StringToken) {
|
||||||
|
Some(self.parse_string_literal()?)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
items.push(Item::Mod {
|
items.push(Item::Mod {
|
||||||
name: self.parse_name()?,
|
name,
|
||||||
absolute: None,
|
absolute: None,
|
||||||
|
path,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Some(Keyword::Set)
|
Some(Keyword::Set)
|
||||||
|
@ -444,3 +444,52 @@ fn dotenv_settings_in_submodule_are_ignored() {
|
|||||||
.stdout("dotenv-value\n")
|
.stdout("dotenv-value\n")
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn modules_may_specify_path() {
|
||||||
|
Test::new()
|
||||||
|
.write("commands/foo.just", "foo:\n @echo FOO")
|
||||||
|
.justfile(
|
||||||
|
"
|
||||||
|
mod foo 'commands/foo.just'
|
||||||
|
",
|
||||||
|
)
|
||||||
|
.test_round_trip(false)
|
||||||
|
.arg("--unstable")
|
||||||
|
.arg("foo")
|
||||||
|
.arg("foo")
|
||||||
|
.stdout("FOO\n")
|
||||||
|
.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn modules_with_paths_are_dumped_correctly() {
|
||||||
|
Test::new()
|
||||||
|
.write("commands/foo.just", "foo:\n @echo FOO")
|
||||||
|
.justfile(
|
||||||
|
"
|
||||||
|
mod foo 'commands/foo.just'
|
||||||
|
",
|
||||||
|
)
|
||||||
|
.test_round_trip(false)
|
||||||
|
.arg("--unstable")
|
||||||
|
.arg("--dump")
|
||||||
|
.stdout("mod foo 'commands/foo.just'\n")
|
||||||
|
.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn recipes_may_be_named_mod() {
|
||||||
|
Test::new()
|
||||||
|
.justfile(
|
||||||
|
"
|
||||||
|
mod foo:
|
||||||
|
@echo FOO
|
||||||
|
",
|
||||||
|
)
|
||||||
|
.test_round_trip(false)
|
||||||
|
.arg("mod")
|
||||||
|
.arg("bar")
|
||||||
|
.stdout("FOO\n")
|
||||||
|
.run();
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user