Allow multiple imports of the same file in different modules (#2065)
This commit is contained in:
parent
d6b2e6bad2
commit
b9f63f1494
@ -61,7 +61,7 @@ impl Compiler {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if let Some(import) = import {
|
if let Some(import) = import {
|
||||||
if srcs.contains_key(&import) {
|
if current.file_path.contains(&import) {
|
||||||
return Err(Error::CircularImport {
|
return Err(Error::CircularImport {
|
||||||
current: current.path,
|
current: current.path,
|
||||||
import,
|
import,
|
||||||
@ -87,7 +87,7 @@ impl Compiler {
|
|||||||
.lexiclean();
|
.lexiclean();
|
||||||
|
|
||||||
if import.is_file() {
|
if import.is_file() {
|
||||||
if srcs.contains_key(&import) {
|
if current.file_path.contains(&import) {
|
||||||
return Err(Error::CircularImport {
|
return Err(Error::CircularImport {
|
||||||
current: current.path,
|
current: current.path,
|
||||||
import,
|
import,
|
||||||
@ -229,26 +229,11 @@ recipe_b: recipe_c
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn recursive_includes_fail() {
|
fn recursive_includes_fail() {
|
||||||
let justfile_a = r#"
|
|
||||||
# A comment at the top of the file
|
|
||||||
import "./subdir/justfile_b"
|
|
||||||
|
|
||||||
some_recipe: recipe_b
|
|
||||||
echo "some recipe"
|
|
||||||
|
|
||||||
"#;
|
|
||||||
|
|
||||||
let justfile_b = r#"
|
|
||||||
import "../justfile"
|
|
||||||
|
|
||||||
recipe_b:
|
|
||||||
echo "recipe b"
|
|
||||||
"#;
|
|
||||||
let tmp = temptree! {
|
let tmp = temptree! {
|
||||||
justfile: justfile_a,
|
justfile: "import './subdir/b'\na: b",
|
||||||
subdir: {
|
subdir: {
|
||||||
justfile_b: justfile_b
|
b: "import '../justfile'\nb:"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let loader = Loader::new();
|
let loader = Loader::new();
|
||||||
@ -257,8 +242,8 @@ recipe_b:
|
|||||||
let loader_output = Compiler::compile(false, &loader, &justfile_a_path).unwrap_err();
|
let loader_output = Compiler::compile(false, &loader, &justfile_a_path).unwrap_err();
|
||||||
|
|
||||||
assert_matches!(loader_output, Error::CircularImport { current, import }
|
assert_matches!(loader_output, Error::CircularImport { current, import }
|
||||||
if current == tmp.path().join("subdir").join("justfile_b").lexiclean() &&
|
if current == tmp.path().join("subdir").join("b").lexiclean() &&
|
||||||
import == tmp.path().join("justfile").lexiclean()
|
import == tmp.path().join("justfile").lexiclean()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ use super::*;
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate) struct Source<'src> {
|
pub(crate) struct Source<'src> {
|
||||||
pub(crate) file_depth: u32,
|
pub(crate) file_depth: u32,
|
||||||
|
pub(crate) file_path: Vec<PathBuf>,
|
||||||
pub(crate) namepath: Namepath<'src>,
|
pub(crate) namepath: Namepath<'src>,
|
||||||
pub(crate) path: PathBuf,
|
pub(crate) path: PathBuf,
|
||||||
pub(crate) submodule_depth: u32,
|
pub(crate) submodule_depth: u32,
|
||||||
@ -13,6 +14,7 @@ impl<'src> Source<'src> {
|
|||||||
pub(crate) fn root(path: &Path) -> Self {
|
pub(crate) fn root(path: &Path) -> Self {
|
||||||
Self {
|
Self {
|
||||||
file_depth: 0,
|
file_depth: 0,
|
||||||
|
file_path: vec![path.into()],
|
||||||
namepath: Namepath::default(),
|
namepath: Namepath::default(),
|
||||||
path: path.into(),
|
path: path.into(),
|
||||||
submodule_depth: 0,
|
submodule_depth: 0,
|
||||||
@ -23,6 +25,12 @@ impl<'src> Source<'src> {
|
|||||||
pub(crate) fn import(&self, path: PathBuf) -> Self {
|
pub(crate) fn import(&self, path: PathBuf) -> Self {
|
||||||
Self {
|
Self {
|
||||||
file_depth: self.file_depth + 1,
|
file_depth: self.file_depth + 1,
|
||||||
|
file_path: self
|
||||||
|
.file_path
|
||||||
|
.clone()
|
||||||
|
.into_iter()
|
||||||
|
.chain(iter::once(path.clone()))
|
||||||
|
.collect(),
|
||||||
namepath: self.namepath.clone(),
|
namepath: self.namepath.clone(),
|
||||||
path,
|
path,
|
||||||
submodule_depth: self.submodule_depth,
|
submodule_depth: self.submodule_depth,
|
||||||
@ -33,10 +41,16 @@ impl<'src> Source<'src> {
|
|||||||
pub(crate) fn module(&self, name: Name<'src>, path: PathBuf) -> Self {
|
pub(crate) fn module(&self, name: Name<'src>, path: PathBuf) -> Self {
|
||||||
Self {
|
Self {
|
||||||
file_depth: self.file_depth + 1,
|
file_depth: self.file_depth + 1,
|
||||||
|
file_path: self
|
||||||
|
.file_path
|
||||||
|
.clone()
|
||||||
|
.into_iter()
|
||||||
|
.chain(iter::once(path.clone()))
|
||||||
|
.collect(),
|
||||||
namepath: self.namepath.join(name),
|
namepath: self.namepath.join(name),
|
||||||
|
path: path.clone(),
|
||||||
submodule_depth: self.submodule_depth + 1,
|
submodule_depth: self.submodule_depth + 1,
|
||||||
working_directory: path.parent().unwrap().into(),
|
working_directory: path.parent().unwrap().into(),
|
||||||
path,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -361,3 +361,22 @@ fn recipes_imported_in_root_run_in_command_line_provided_working_directory() {
|
|||||||
.stdout("BAZBAZ")
|
.stdout("BAZBAZ")
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn reused_import_are_allowed() {
|
||||||
|
Test::new()
|
||||||
|
.justfile(
|
||||||
|
"
|
||||||
|
import 'a'
|
||||||
|
import 'b'
|
||||||
|
|
||||||
|
bar:
|
||||||
|
",
|
||||||
|
)
|
||||||
|
.tree(tree! {
|
||||||
|
a: "import 'c'",
|
||||||
|
b: "import 'c'",
|
||||||
|
c: "",
|
||||||
|
})
|
||||||
|
.run();
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user