Allow shebang lines so justfiles can be used as scripts (#393)

This commit is contained in:
Casey Rodarmor 2019-04-08 14:28:17 -07:00 committed by GitHub
parent cee9ac21e0
commit 37639d68d7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 27 additions and 40 deletions

View File

@ -653,6 +653,27 @@ $ just foo/build
$ just foo/
```
=== Just Scripts
By adding a shebang line to the top of a justfile and making it executable, `just` can be used as an interpreter for scripts:
```sh
$ cat > script <<EOF
#!/usr/bin/env just --justfile
foo:
echo foo
EOF
$ chmod +x script
$ ./script foo
echo foo
foo
```
When a script with a shebang is executed, the system supplies the path to the script as an argument to the command in the shebang. So, with a shebang of `#!/usr/bin/env just --justfile`, the command will be `/usr/bin/env just --justfile PATH_TO_SCRIPT`.
With the above shebang, `just` will change its working directory to the location of the script. If you'd rather leave the working directory unchanged, use `#!/usr/bin/env just --working-directory . --justfile`.
== Frequently Asked Questions
=== What are the idiosyncrasies of make that just avoids?

4
justfile Normal file → Executable file
View File

@ -1,3 +1,7 @@
#!/usr/bin/env just --justfile
# ^ A shebang isn't required, but allows a justfile to be executed
# like a script, with `./justfile test`, for example.
bt='0'
export RUST_BACKTRACE=bt

View File

@ -62,7 +62,6 @@ pub enum CompilationErrorKind<'a> {
MixedLeadingWhitespace {
whitespace: &'a str,
},
OuterShebang,
ParameterFollowsVariadicParameter {
parameter: &'a str,
},
@ -229,9 +228,6 @@ impl<'a> Display for CompilationError<'a> {
show_whitespace(found)
)?;
}
OuterShebang => {
writeln!(f, "`#!` is reserved syntax outside of recipes")?;
}
UnknownDependency { recipe, unknown } => {
writeln!(
f,

View File

@ -135,7 +135,7 @@ impl<'a> Lexer<'a> {
static ref BACKTICK: Regex = token(r"`[^`\n\r]*`");
static ref COLON: Regex = token(r":");
static ref COMMA: Regex = token(r",");
static ref COMMENT: Regex = token(r"#([^!\n\r][^\n\r]*)?\r?$");
static ref COMMENT: Regex = token(r"#([^\n\r][^\n\r]*)?\r?$");
static ref EOF: Regex = token(r"\z");
static ref EOL: Regex = token(r"\n|\r\n");
static ref EQUALS: Regex = token(r"=");
@ -322,8 +322,6 @@ impl<'a> Lexer<'a> {
return Err(self.error(UnterminatedString));
}
(prefix, &self.rest[start..content_end + 1], StringToken)
} else if self.rest.starts_with("#!") {
return Err(self.error(OuterShebang));
} else {
return Err(self.error(UnknownStartOfToken));
};
@ -340,7 +338,7 @@ impl<'a> Lexer<'a> {
_ => {
return Err(last.error(Internal {
message: format!("zero length token: {:?}", last),
}))
}));
}
}
}
@ -647,16 +645,6 @@ c: b
kind: InconsistentLeadingWhitespace{expected: "\t\t", found: "\t "},
}
error_test! {
name: tokenize_outer_shebang,
input: "#!/usr/bin/env bash",
index: 0,
line: 0,
column: 0,
width: None,
kind: OuterShebang,
}
error_test! {
name: tokenize_unknown,
input: "~",

View File

@ -578,28 +578,6 @@ wut:
status: EXIT_SUCCESS,
}
integration_test! {
name: outer_shebang,
justfile: r#"#!/lol/wut
export FOO = "a"
baz = "c"
export BAR = "b"
export ABC = FOO + BAR + baz
wut:
#!/bin/sh
echo $FOO $BAR $ABC
"#,
args: (),
stdout: "",
stderr: "error: `#!` is reserved syntax outside of recipes
|
1 | #!/lol/wut
| ^
",
status: EXIT_FAILURE,
}
integration_test! {
name: export_shebang,
justfile: r#"