Note shebang line splitting inconsistency in readme (#757)
This commit is contained in:
parent
c647efa200
commit
7ae890ce61
@ -1224,6 +1224,15 @@ When a script with a shebang is executed, the system supplies the path to the sc
|
|||||||
|
|
||||||
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`.
|
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`.
|
||||||
|
|
||||||
|
Note: Shebang line splitting is not consistent across operating systems. The previous examples have only been tested on macOS. On Linux, you may need to pass the `-S` flag to `env`:
|
||||||
|
|
||||||
|
```
|
||||||
|
#!/usr/bin/env -S just --justfile
|
||||||
|
|
||||||
|
default:
|
||||||
|
echo foo
|
||||||
|
```
|
||||||
|
|
||||||
== Miscellanea
|
== Miscellanea
|
||||||
|
|
||||||
=== Companion Tools
|
=== Companion Tools
|
||||||
|
@ -54,10 +54,10 @@ impl Display for CompilationError<'_> {
|
|||||||
|
|
||||||
InvalidEscapeSequence { character } => {
|
InvalidEscapeSequence { character } => {
|
||||||
let representation = match character {
|
let representation = match character {
|
||||||
'`' => r"\`".to_string(),
|
'`' => r"\`".to_owned(),
|
||||||
'\\' => r"\".to_string(),
|
'\\' => r"\".to_owned(),
|
||||||
'\'' => r"'".to_string(),
|
'\'' => r"'".to_owned(),
|
||||||
'"' => r#"""#.to_string(),
|
'"' => r#"""#.to_owned(),
|
||||||
_ => character.escape_default().collect(),
|
_ => character.escape_default().collect(),
|
||||||
};
|
};
|
||||||
writeln!(f, "`\\{}` is not a valid escape sequence", representation)?;
|
writeln!(f, "`\\{}` is not a valid escape sequence", representation)?;
|
||||||
|
@ -512,19 +512,21 @@ impl Config {
|
|||||||
|
|
||||||
match &self.subcommand {
|
match &self.subcommand {
|
||||||
Choose { overrides, chooser } =>
|
Choose { overrides, chooser } =>
|
||||||
self.choose(justfile, &search, overrides, chooser.as_deref()),
|
self.choose(justfile, &search, overrides, chooser.as_deref())?,
|
||||||
Dump => Self::dump(justfile),
|
Dump => Self::dump(justfile),
|
||||||
Evaluate { overrides } => self.run(justfile, &search, overrides, &[]),
|
Evaluate { overrides } => self.run(justfile, &search, overrides, &[])?,
|
||||||
List => self.list(justfile),
|
List => self.list(justfile),
|
||||||
Run {
|
Run {
|
||||||
arguments,
|
arguments,
|
||||||
overrides,
|
overrides,
|
||||||
} => self.run(justfile, &search, overrides, arguments),
|
} => self.run(justfile, &search, overrides, arguments)?,
|
||||||
Show { ref name } => Self::show(&name, justfile),
|
Show { ref name } => Self::show(&name, justfile)?,
|
||||||
Summary => self.summary(justfile),
|
Summary => self.summary(justfile),
|
||||||
Variables => Self::variables(justfile),
|
Variables => Self::variables(justfile),
|
||||||
Completions { .. } | Edit | Init => unreachable!(),
|
Completions { .. } | Edit | Init => unreachable!(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn choose(
|
fn choose(
|
||||||
@ -620,9 +622,8 @@ impl Config {
|
|||||||
self.run(justfile, search, overrides, &recipes)
|
self.run(justfile, search, overrides, &recipes)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dump(justfile: Justfile) -> Result<(), i32> {
|
fn dump(justfile: Justfile) {
|
||||||
println!("{}", justfile);
|
println!("{}", justfile);
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn edit(search: &Search) -> Result<(), i32> {
|
pub(crate) fn edit(search: &Search) -> Result<(), i32> {
|
||||||
@ -674,7 +675,7 @@ impl Config {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn list(&self, justfile: Justfile) -> Result<(), i32> {
|
fn list(&self, justfile: Justfile) {
|
||||||
// Construct a target to alias map.
|
// Construct a target to alias map.
|
||||||
let mut recipe_aliases: BTreeMap<&str, Vec<&str>> = BTreeMap::new();
|
let mut recipe_aliases: BTreeMap<&str, Vec<&str>> = BTreeMap::new();
|
||||||
for alias in justfile.aliases.values() {
|
for alias in justfile.aliases.values() {
|
||||||
@ -756,8 +757,6 @@ impl Config {
|
|||||||
println!();
|
println!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run(
|
fn run(
|
||||||
@ -798,7 +797,7 @@ impl Config {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn summary(&self, justfile: Justfile) -> Result<(), i32> {
|
fn summary(&self, justfile: Justfile) {
|
||||||
if justfile.count() == 0 {
|
if justfile.count() == 0 {
|
||||||
eprintln!("Justfile contains no recipes.");
|
eprintln!("Justfile contains no recipes.");
|
||||||
} else {
|
} else {
|
||||||
@ -810,10 +809,9 @@ impl Config {
|
|||||||
.join(" ");
|
.join(" ");
|
||||||
println!("{}", summary);
|
println!("{}", summary);
|
||||||
}
|
}
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn variables(justfile: Justfile) -> Result<(), i32> {
|
fn variables(justfile: Justfile) {
|
||||||
for (i, (_, assignment)) in justfile.assignments.iter().enumerate() {
|
for (i, (_, assignment)) in justfile.assignments.iter().enumerate() {
|
||||||
if i > 0 {
|
if i > 0 {
|
||||||
print!(" ");
|
print!(" ");
|
||||||
@ -821,7 +819,6 @@ impl Config {
|
|||||||
print!("{}", assignment.name)
|
print!("{}", assignment.name)
|
||||||
}
|
}
|
||||||
println!();
|
println!();
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,7 +212,7 @@ impl<'src, 'run> Evaluator<'src, 'run> {
|
|||||||
String::new()
|
String::new()
|
||||||
} else {
|
} else {
|
||||||
return Err(RuntimeError::Internal {
|
return Err(RuntimeError::Internal {
|
||||||
message: "missing parameter without default".to_string(),
|
message: "missing parameter without default".to_owned(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else if parameter.kind.is_variadic() {
|
} else if parameter.kind.is_variadic() {
|
||||||
|
@ -34,19 +34,19 @@ impl Function {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn arch(_context: &FunctionContext) -> Result<String, String> {
|
fn arch(_context: &FunctionContext) -> Result<String, String> {
|
||||||
Ok(target::arch().to_string())
|
Ok(target::arch().to_owned())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn os(_context: &FunctionContext) -> Result<String, String> {
|
fn os(_context: &FunctionContext) -> Result<String, String> {
|
||||||
Ok(target::os().to_string())
|
Ok(target::os().to_owned())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn os_family(_context: &FunctionContext) -> Result<String, String> {
|
fn os_family(_context: &FunctionContext) -> Result<String, String> {
|
||||||
Ok(target::os_family().to_string())
|
Ok(target::os_family().to_owned())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn invocation_directory(context: &FunctionContext) -> Result<String, String> {
|
fn invocation_directory(context: &FunctionContext) -> Result<String, String> {
|
||||||
Platform::to_shell_path(
|
Platform::convert_native_path(
|
||||||
&context.search.working_directory,
|
&context.search.working_directory,
|
||||||
context.invocation_directory,
|
context.invocation_directory,
|
||||||
)
|
)
|
||||||
@ -115,7 +115,7 @@ fn env_var_or_default(
|
|||||||
}
|
}
|
||||||
|
|
||||||
match env::var(key) {
|
match env::var(key) {
|
||||||
Err(NotPresent) => Ok(default.to_string()),
|
Err(NotPresent) => Ok(default.to_owned()),
|
||||||
Err(NotUnicode(os_string)) => Err(format!(
|
Err(NotUnicode(os_string)) => Err(format!(
|
||||||
"environment variable `{}` not unicode: {:?}",
|
"environment variable `{}` not unicode: {:?}",
|
||||||
key, os_string
|
key, os_string
|
||||||
|
@ -54,7 +54,7 @@ impl InterruptHandler {
|
|||||||
pub(crate) fn unblock(&mut self) {
|
pub(crate) fn unblock(&mut self) {
|
||||||
if self.blocks == 0 {
|
if self.blocks == 0 {
|
||||||
eprintln!("{}", RuntimeError::Internal {
|
eprintln!("{}", RuntimeError::Internal {
|
||||||
message: "attempted to unblock interrupt handler, but handler was not blocked".to_string(),
|
message: "attempted to unblock interrupt handler, but handler was not blocked".to_owned(),
|
||||||
});
|
});
|
||||||
std::process::exit(EXIT_FAILURE);
|
std::process::exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
clippy::string_add,
|
clippy::string_add,
|
||||||
clippy::struct_excessive_bools,
|
clippy::struct_excessive_bools,
|
||||||
clippy::too_many_lines,
|
clippy::too_many_lines,
|
||||||
|
clippy::unnecessary_wraps,
|
||||||
clippy::unreachable,
|
clippy::unreachable,
|
||||||
clippy::unwrap_in_result,
|
clippy::unwrap_in_result,
|
||||||
clippy::unwrap_used,
|
clippy::unwrap_used,
|
||||||
|
@ -25,7 +25,7 @@ pub(crate) fn output(mut command: Command) -> Result<String, OutputError> {
|
|||||||
} else {
|
} else {
|
||||||
utf8
|
utf8
|
||||||
}
|
}
|
||||||
.to_string(),
|
.to_owned(),
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -527,7 +527,7 @@ impl<'tokens, 'src> Parser<'tokens, 'src> {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
_ => Err(token.error(CompilationErrorKind::Internal {
|
_ => Err(token.error(CompilationErrorKind::Internal {
|
||||||
message: "`Parser::parse_string_literal` called on non-string token".to_string(),
|
message: "`Parser::parse_string_literal` called on non-string token".to_owned(),
|
||||||
})),
|
})),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ impl PlatformInterface for Platform {
|
|||||||
exit_status.signal()
|
exit_status.signal()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_shell_path(_working_directory: &Path, path: &Path) -> Result<String, String> {
|
fn convert_native_path(_working_directory: &Path, path: &Path) -> Result<String, String> {
|
||||||
path
|
path
|
||||||
.to_str()
|
.to_str()
|
||||||
.map(str::to_string)
|
.map(str::to_string)
|
||||||
@ -91,7 +91,7 @@ impl PlatformInterface for Platform {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_shell_path(working_directory: &Path, path: &Path) -> Result<String, String> {
|
fn convert_native_path(working_directory: &Path, path: &Path) -> Result<String, String> {
|
||||||
// Translate path from windows style to unix style
|
// Translate path from windows style to unix style
|
||||||
let mut cygpath = Command::new("cygpath");
|
let mut cygpath = Command::new("cygpath");
|
||||||
cygpath.current_dir(working_directory);
|
cygpath.current_dir(working_directory);
|
||||||
|
@ -18,5 +18,5 @@ pub(crate) trait PlatformInterface {
|
|||||||
fn signal_from_exit_status(exit_status: process::ExitStatus) -> Option<i32>;
|
fn signal_from_exit_status(exit_status: process::ExitStatus) -> Option<i32>;
|
||||||
|
|
||||||
/// Translate a path from a "native" path to a path the interpreter expects
|
/// Translate a path from a "native" path to a path the interpreter expects
|
||||||
fn to_shell_path(working_directory: &Path, path: &Path) -> Result<String, String>;
|
fn convert_native_path(working_directory: &Path, path: &Path) -> Result<String, String>;
|
||||||
}
|
}
|
||||||
|
@ -154,7 +154,7 @@ impl<'src, D> Recipe<'src, D> {
|
|||||||
let shebang_line = evaluated_lines
|
let shebang_line = evaluated_lines
|
||||||
.first()
|
.first()
|
||||||
.ok_or_else(|| RuntimeError::Internal {
|
.ok_or_else(|| RuntimeError::Internal {
|
||||||
message: "evaluated_lines was empty".to_string(),
|
message: "evaluated_lines was empty".to_owned(),
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let Shebang {
|
let Shebang {
|
||||||
@ -195,7 +195,7 @@ impl<'src, D> Recipe<'src, D> {
|
|||||||
Err(io_error) => {
|
Err(io_error) => {
|
||||||
return Err(RuntimeError::Shebang {
|
return Err(RuntimeError::Shebang {
|
||||||
recipe: self.name(),
|
recipe: self.name(),
|
||||||
command: interpreter.to_string(),
|
command: interpreter.to_owned(),
|
||||||
argument: argument.map(String::from),
|
argument: argument.map(String::from),
|
||||||
io_error,
|
io_error,
|
||||||
});
|
});
|
||||||
|
@ -4,7 +4,7 @@ use executable_path::executable_path;
|
|||||||
use test_utilities::tempdir;
|
use test_utilities::tempdir;
|
||||||
|
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
fn to_shell_path(path: &Path) -> String {
|
fn convert_native_path(path: &Path) -> String {
|
||||||
fs::canonicalize(path)
|
fs::canonicalize(path)
|
||||||
.expect("canonicalize failed")
|
.expect("canonicalize failed")
|
||||||
.to_str()
|
.to_str()
|
||||||
@ -13,7 +13,7 @@ fn to_shell_path(path: &Path) -> String {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
fn to_shell_path(path: &Path) -> String {
|
fn convert_native_path(path: &Path) -> String {
|
||||||
// Translate path from windows style to unix style
|
// Translate path from windows style to unix style
|
||||||
let mut cygpath = process::Command::new("cygpath");
|
let mut cygpath = process::Command::new("cygpath");
|
||||||
cygpath.arg("--unix");
|
cygpath.arg("--unix");
|
||||||
@ -60,7 +60,7 @@ fn test_invocation_directory() {
|
|||||||
let mut failure = false;
|
let mut failure = false;
|
||||||
|
|
||||||
let expected_status = 0;
|
let expected_status = 0;
|
||||||
let expected_stdout = to_shell_path(&subdir) + "\n";
|
let expected_stdout = convert_native_path(&subdir) + "\n";
|
||||||
let expected_stderr = "";
|
let expected_stderr = "";
|
||||||
|
|
||||||
let status = output.status.code().unwrap();
|
let status = output.status.code().unwrap();
|
||||||
|
Loading…
Reference in New Issue
Block a user