Skip to content

Commit

Permalink
Run recipes with working directory set to submodule directory (#1788)
Browse files Browse the repository at this point in the history
  • Loading branch information
casey authored Dec 29, 2023
1 parent 94b3af6 commit a1bd70a
Show file tree
Hide file tree
Showing 11 changed files with 101 additions and 25 deletions.
4 changes: 2 additions & 2 deletions src/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ impl Compiler {
let (relative, src) = loader.load(root, &current)?;
loaded.push(relative.into());
let tokens = Lexer::lex(relative, src)?;
let mut ast = Parser::parse(&tokens)?;
let mut ast = Parser::parse(current != root, &current, &tokens)?;

paths.insert(current.clone(), relative.into());
srcs.insert(current.clone(), src);
Expand Down Expand Up @@ -120,7 +120,7 @@ impl Compiler {
#[cfg(test)]
pub(crate) fn test_compile(src: &str) -> CompileResult<Justfile> {
let tokens = Lexer::test_lex(src)?;
let ast = Parser::parse(&tokens)?;
let ast = Parser::parse(false, &PathBuf::new(), &tokens)?;
let root = PathBuf::from("justfile");
let mut asts: HashMap<PathBuf, Ast> = HashMap::new();
asts.insert(root.clone(), ast);
Expand Down
1 change: 0 additions & 1 deletion src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ pub(crate) fn chooser_default(justfile: &Path) -> OsString {
}

#[derive(Debug, PartialEq)]
#[allow(clippy::struct_excessive_bools)]
pub(crate) struct Config {
pub(crate) check: bool,
pub(crate) color: Color,
Expand Down
1 change: 0 additions & 1 deletion src/justfile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,6 @@ impl<'src> Justfile<'src> {
.or_else(|| self.aliases.get(name).map(|alias| alias.target.as_ref()))
}

#[allow(clippy::too_many_arguments)]
fn invocation<'run>(
&'run self,
depth: usize,
Expand Down
6 changes: 5 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,13 @@
clippy::let_underscore_untyped,
clippy::needless_pass_by_value,
clippy::similar_names,
clippy::struct_excessive_bools,
clippy::struct_field_names,
clippy::too_many_arguments,
clippy::too_many_lines,
clippy::unnecessary_wraps,
clippy::wildcard_imports
clippy::wildcard_imports,
overlapping_range_endpoints
)]

pub(crate) use {
Expand Down
34 changes: 21 additions & 13 deletions src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,22 +32,28 @@ pub(crate) struct Parser<'tokens, 'src> {
expected: BTreeSet<TokenKind>,
/// Current recursion depth
depth: usize,
/// Path to the file being parsed
path: PathBuf,
/// Parsing a submodule
submodule: bool,
}

impl<'tokens, 'src> Parser<'tokens, 'src> {
/// Parse `tokens` into an `Ast`
pub(crate) fn parse(tokens: &'tokens [Token<'src>]) -> CompileResult<'src, Ast<'src>> {
Self::new(tokens).parse_ast()
}

/// Construct a new Parser from a token stream
fn new(tokens: &'tokens [Token<'src>]) -> Parser<'tokens, 'src> {
pub(crate) fn parse(
submodule: bool,
path: &Path,
tokens: &'tokens [Token<'src>],
) -> CompileResult<'src, Ast<'src>> {
Parser {
next: 0,
depth: 0,
expected: BTreeSet::new(),
next: 0,
path: path.into(),
submodule,
tokens,
depth: 0,
}
.parse_ast()
}

fn error(&self, kind: CompileErrorKind<'src>) -> CompileResult<'src, CompileError<'src>> {
Expand Down Expand Up @@ -707,16 +713,18 @@ impl<'tokens, 'src> Parser<'tokens, 'src> {
let body = self.parse_body()?;

Ok(Recipe {
parameters: positional.into_iter().chain(variadic).collect(),
private: name.lexeme().starts_with('_'),
shebang: body.first().map_or(false, Line::is_shebang),
attributes,
priors,
body,
dependencies,
doc,
name,
parameters: positional.into_iter().chain(variadic).collect(),
path: self.path.clone(),
priors,
private: name.lexeme().starts_with('_'),
quiet,
submodule: self.submodule,
})
}

Expand Down Expand Up @@ -934,7 +942,7 @@ mod tests {
fn test(text: &str, want: Tree) {
let unindented = unindent(text);
let tokens = Lexer::test_lex(&unindented).expect("lexing failed");
let justfile = Parser::parse(&tokens).expect("parsing failed");
let justfile = Parser::parse(false, &PathBuf::new(), &tokens).expect("parsing failed");
let have = justfile.tree();
if have != want {
println!("parsed text: {unindented}");
Expand Down Expand Up @@ -972,7 +980,7 @@ mod tests {
) {
let tokens = Lexer::test_lex(src).expect("Lexing failed in parse test...");

match Parser::parse(&tokens) {
match Parser::parse(false, &PathBuf::new(), &tokens) {
Ok(_) => panic!("Parsing unexpectedly succeeded"),
Err(have) => {
let want = CompileError {
Expand Down
16 changes: 14 additions & 2 deletions src/recipe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,14 @@ pub(crate) struct Recipe<'src, D = Dependency<'src>> {
pub(crate) doc: Option<&'src str>,
pub(crate) name: Name<'src>,
pub(crate) parameters: Vec<Parameter<'src>>,
#[serde(skip)]
pub(crate) path: PathBuf,
pub(crate) priors: usize,
pub(crate) private: bool,
pub(crate) quiet: bool,
pub(crate) shebang: bool,
#[serde(skip)]
pub(crate) submodule: bool,
}

impl<'src, D> Recipe<'src, D> {
Expand Down Expand Up @@ -222,7 +226,11 @@ impl<'src, D> Recipe<'src, D> {
let mut cmd = context.settings.shell_command(config);

if self.change_directory() {
cmd.current_dir(&context.search.working_directory);
cmd.current_dir(if self.submodule {
self.path.parent().unwrap()
} else {
&context.search.working_directory
});
}

cmd.arg(command);
Expand Down Expand Up @@ -358,7 +366,11 @@ impl<'src, D> Recipe<'src, D> {
let mut command = Platform::make_shebang_command(
&path,
if self.change_directory() {
Some(&context.search.working_directory)
if self.submodule {
Some(self.path.parent().unwrap())
} else {
Some(&context.search.working_directory)
}
} else {
None
},
Expand Down
1 change: 0 additions & 1 deletion src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ pub(crate) const WINDOWS_POWERSHELL_SHELL: &str = "powershell.exe";
pub(crate) const WINDOWS_POWERSHELL_ARGS: &[&str] = &["-NoLogo", "-Command"];

#[derive(Debug, PartialEq, Serialize, Default)]
#[allow(clippy::struct_excessive_bools)]
pub(crate) struct Settings<'src> {
pub(crate) allow_duplicate_recipes: bool,
pub(crate) dotenv_filename: Option<String>,
Expand Down
3 changes: 2 additions & 1 deletion src/testing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ pub(crate) fn analysis_error(
) {
let tokens = Lexer::test_lex(src).expect("Lexing failed in parse test...");

let ast = Parser::parse(&tokens).expect("Parsing failed in analysis test...");
let ast =
Parser::parse(false, &PathBuf::new(), &tokens).expect("Parsing failed in analysis test...");

let root = PathBuf::from("justfile");
let mut asts: HashMap<PathBuf, Ast> = HashMap::new();
Expand Down
8 changes: 5 additions & 3 deletions src/unresolved_recipe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,16 +45,18 @@ impl<'src> UnresolvedRecipe<'src> {
.collect();

Ok(Recipe {
attributes: self.attributes,
body: self.body,
dependencies,
doc: self.doc,
name: self.name,
parameters: self.parameters,
path: self.path,
priors: self.priors,
private: self.private,
quiet: self.quiet,
shebang: self.shebang,
priors: self.priors,
attributes: self.attributes,
dependencies,
submodule: self.submodule,
})
}
}
36 changes: 36 additions & 0 deletions tests/modules.rs
Original file line number Diff line number Diff line change
Expand Up @@ -493,3 +493,39 @@ fn recipes_may_be_named_mod() {
.stdout("FOO\n")
.run();
}

#[test]
fn submodule_linewise_recipes_run_in_submodule_directory() {
Test::new()
.write("foo/bar", "BAR")
.write("foo/mod.just", "foo:\n @cat bar")
.justfile(
"
mod foo
",
)
.test_round_trip(false)
.arg("--unstable")
.arg("foo")
.arg("foo")
.stdout("BAR")
.run();
}

#[test]
fn submodule_shebang_recipes_run_in_submodule_directory() {
Test::new()
.write("foo/bar", "BAR")
.write("foo/mod.just", "foo:\n #!/bin/sh\n cat bar")
.justfile(
"
mod foo
",
)
.test_round_trip(false)
.arg("--unstable")
.arg("foo")
.arg("foo")
.stdout("BAR")
.run();
}
16 changes: 16 additions & 0 deletions tests/shebang.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use super::*;

#[cfg(windows)]
test! {
name: powershell,
Expand Down Expand Up @@ -41,3 +43,17 @@ default:
"#,
stdout: "Hello-World\r\n",
}

#[test]
fn simple() {
Test::new()
.justfile(
"
foo:
#!/bin/sh
echo bar
",
)
.stdout("bar\n")
.run();
}

0 comments on commit a1bd70a

Please sign in to comment.