Skip to content

Commit

Permalink
Expand tilde in import and module paths (#1792)
Browse files Browse the repository at this point in the history
  • Loading branch information
casey authored Dec 29, 2023
1 parent b21819d commit f039701
Show file tree
Hide file tree
Showing 7 changed files with 142 additions and 4 deletions.
70 changes: 70 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ camino = "1.0.4"
clap = { version = "2.33.0", features = ["wrap_help"] }
ctrlc = { version = "3.1.1", features = ["termination"] }
derivative = "2.0.0"
dirs = "5.0.1"
dotenvy = "0.15"
edit-distance = "2.0.0"
env_logger = "0.10.0"
Expand Down
17 changes: 15 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2358,7 +2358,8 @@ A
```

The `import` path can be absolute or relative to the location of the justfile
containing it.
containing it. A leading `~/` in the import path is replaced with the current
users home directory.

Justfiles are insensitive to order, so included files can reference variables
and recipes defined after the `import` statement.
Expand Down Expand Up @@ -2406,7 +2407,19 @@ If a module is named `foo`, just will search for the module file in `foo.just`,
`foo/mod.just`, `foo/justfile`, and `foo/.justfile`. In the latter two cases,
the module file may have any capitalization.

Environment files are loaded for the root justfile.
Module statements may be of the form:

```mf
mod foo 'PATH'
```

Which loads the module's source file from `PATH`, instead of from the usual
locations. A leading `~/` in `PATH` is replaced with the current user's home
directory.

Environment files are only loaded for the root justfile, and loaded environment
variables are available in submodules. Settings in submodules that affect
enviroment file loading are ignored.

Recipes in submodules without the `[no-cd]` attribute run with the working
directory set to the directory containing the submodule source file.
Expand Down
18 changes: 16 additions & 2 deletions src/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ impl Compiler {
let parent = current.parent().unwrap();

let import = if let Some(path) = path {
parent.join(&path.cooked)
parent.join(Self::expand_tilde(&path.cooked)?)
} else {
Self::find_module_file(parent, *name)?
};
Expand All @@ -53,7 +53,11 @@ impl Compiler {
stack.push((import, depth + 1));
}
Item::Import { relative, absolute } => {
let import = current.parent().unwrap().join(&relative.cooked).lexiclean();
let import = current
.parent()
.unwrap()
.join(Self::expand_tilde(&relative.cooked)?)
.lexiclean();
if srcs.contains_key(&import) {
return Err(Error::CircularImport { current, import });
}
Expand Down Expand Up @@ -117,6 +121,16 @@ impl Compiler {
}
}

fn expand_tilde(path: &str) -> RunResult<'static, PathBuf> {
Ok(if let Some(path) = path.strip_prefix("~/") {
dirs::home_dir()
.ok_or(Error::Homedir)?
.join(path.trim_start_matches('/'))
} else {
PathBuf::from(path)
})
}

#[cfg(test)]
pub(crate) fn test_compile(src: &str) -> CompileResult<Justfile> {
let tokens = Lexer::test_lex(src)?;
Expand Down
4 changes: 4 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ pub(crate) enum Error<'src> {
GetConfirmation {
io_error: io::Error,
},
Homedir,
InitExists {
justfile: PathBuf,
},
Expand Down Expand Up @@ -347,6 +348,9 @@ impl<'src> ColorDisplay for Error<'src> {
GetConfirmation { io_error } => {
write!(f, "Failed to read confirmation from stdin: {io_error}")?;
}
Homedir => {
write!(f, "Failed to get homedir")?;
}
InitExists { justfile } => {
write!(f, "Justfile `{}` already exists", justfile.display())?;
}
Expand Down
17 changes: 17 additions & 0 deletions tests/imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,3 +152,20 @@ fn recipes_in_import_are_overridden_by_recipes_in_parent() {
.stdout("ROOT\n")
.run();
}

#[cfg(not(windows))]
#[test]
fn import_paths_beginning_with_tilde_are_expanded_to_homdir() {
Test::new()
.write("foobar/mod.just", "foo:\n @echo FOOBAR")
.justfile(
"
import '~/mod.just'
",
)
.test_round_trip(false)
.arg("foo")
.stdout("FOOBAR\n")
.env("HOME", "foobar")
.run();
}
19 changes: 19 additions & 0 deletions tests/modules.rs
Original file line number Diff line number Diff line change
Expand Up @@ -529,3 +529,22 @@ fn submodule_shebang_recipes_run_in_submodule_directory() {
.stdout("BAR")
.run();
}

#[cfg(not(windows))]
#[test]
fn module_paths_beginning_with_tilde_are_expanded_to_homdir() {
Test::new()
.write("foobar/mod.just", "foo:\n @echo FOOBAR")
.justfile(
"
mod foo '~/mod.just'
",
)
.test_round_trip(false)
.arg("--unstable")
.arg("foo")
.arg("foo")
.stdout("FOOBAR\n")
.env("HOME", "foobar")
.run();
}

0 comments on commit f039701

Please sign in to comment.