Comments (11)
Try removing -c
from the shebang. -c
instructs the shell that the first positional argument is not a file, but a string of commands to run. But shebang recipes are run as a temporary file, so shebangs with -c
won't work correctly.
from just.
I'm not sure which -c
you wanted me to remove, on the Justfile
or the recipe
but I can't get either scenario to help me.
Using the script:
set shell := ['nu', '-c']
_default:
@{{just_executable()}} -f {{justfile()}} --list --unsorted
fail:
#!nu
let var = "World"
print $"Hello ($var)"
@work:
let var = "World"; \
print $"Hello ($var)"
I get:
# just fail
error: Recipe `fail` with shebang `#!nu` execution error: No such file or directory (os error 2)
# just work
Hello World
If I switch the Justfile shell line to remove the -c
:
set shell := ['nu']
I get:
# just fail
error: Recipe `fail` with shebang `#!nu` execution error: No such file or directory (os error 2)
# just work
Error: nu::shell::file_not_found
× File not found
╭─[source:1:1]
1 │ nu
· ▲
· ╰── Could not access file 'let var = "World"; print $"Hello ($var)"': No such file or directory (os error 2)
╰────
from just.
Currently, I don't think there's a good workaround for this. Shebang paths must be absolute, so there's no way to get them working on Windows and Unix without hackery.
I think the best solution would be implementing #1479, this would allow you to write:
[script("nu", "-c")]
foo:
let var = "World"
print $"Hello ($var)"
The foo
recipe would be executed as a shebang recipe, and it would use whatever you provided in the [script(…)]
annotation to run the script, which would work work on both Windows and Unix.
I'm a bit unsure about the name of the annotation. In current parlance, recipes are called either "shebang" recipes or "linewise" recipes, but [shebang(…)]
is not a good name for the annotation, since it wouldn't actually be executed with a shebang. So maybe, along with the [script(…)]
annotation, we would actually change references to "shenbang recipes" in the docs and code to call them "script recipes".
from just.
Would it be easier to go the other way and support a flag set linewise = off
to opt out of line mode for the file?
from just.
I'm not sure that would make a ton of sense, since if linewise
is off, but you don't specify one otherwise, what is the interpreter?
from just.
The default interpreter set shell := ['nu', '-c']
is actually able to find the nu
from my PATH
. The only reason I'm trying to do shebang is to opt out of linemode.
from just.
The shell
interpreter is used in more places than just linewise scripts. For example, it's used in backticks, which aren't written to disk, but instead passed as an argument. So the shell
interpreter has to take the command as an argument, whereas the shebang interpreter (or a hypothetical [script(…)]
attribute interpreter) has to take a path to the script, which has been written to disk.
Se the set shell
interpreter can't be used for this purpose.
from just.
I assumed when I specified the shell
interpreter today that every recipe line
invocation got it's own copy of a configured shell instance. So thought adding something like set linewise = off
could just apply to the usage of the shell interpreter on the recipe toggling it from constructing one per line to reusing it.
from just.
Ah, gotcha. It generally isn't possible to reuse an interpreter after the process returns. And just concatenating all the lines and running them may be possible, but might run into some argument length limit.
from just.
I had to spend some time reading the code to fully understand what was happening.
The set shell := ['nu', '-c']
works great for run_linewise
because it is forked as a process and thus able to be discovered via PATH. The -c
invokes the single text line one at a time which works great for the run_linewise.
The run_shebang
is writing a temporary preprocessed file, making it executable and invoking it analogous to running it in a standard shell with shebang
semantics in which the absolute path to the shebang executable is a requirement. (So it will never work to specify a shebang
inside the recipe and try to remain platform neutral.)
Really what I'm after is the running essentially the same as run_shebang
but having the make_shebang_command
invoke the shell in my case nu
and pass the file as the first argument followed by the script arguments.
Which is why you earlier indicated that set shell
was used in multiple spots - because the -c
option provided on that was a requirement in the run_linewise
context. And also explains why set linewise = off
wouldn't work (you wouldn't know the command to invoke without the -c
options).
So maybe a set recipe_shell := ['nu']
which if provided is essentially the same code as run_shebang
but launching the specified process with the script as the first argument? But even that either needs someone to fake out the script with #!
or a flag like set linewise=off
to always force the run_shebang
.
from just.
Something like this might work.
let recipe_shell = Some(["nu"]); // Assume some shells may need args to run script?
let script = path;
let (path, args) = if let Some(shell_command) = recipe_shell {
let script = script.to_str().unwrap_or_default();
let mut args = shell_command.to_vec();
args.push(script);
let shell = args.remove(0);
(Path::new(shell).to_path_buf(), Some(args))
} else {
(script, None) // No recipe_shell provided default to running script path
};
// create command to run script
let mut command =
Platform::make_shebang_command(&path, self.working_directory(context.search), shebang)
.map_err(|output_error| Error::Cygpath {
recipe: self.name(),
output_error,
})?;
if let Some(args) = args {
if self.takes_positional_arguments(context.settings) {
command.args(args);
command.args(positional);
} else {
// Had no positional arguments, but still need to pass the args
command.args(args);
}
} else {
if self.takes_positional_arguments(context.settings) {
command.args(positional);
}
}
from just.
Related Issues (20)
- Add a --list-paths to output list of recipe paths only HOT 4
- Submodules should be groupable (or have their own group) HOT 6
- Passing arguments for python different than node? I needed to add -- HOT 4
- Parser support for attributes with multiple arguments HOT 1
- Module improvement tracking issue HOT 2
- No .ps1 extension added when pwsh.exe is started via third-party tool HOT 6
- Possible to get autocompletions working in Warp?
- dotenv-path unexpectedly loads .env from parent directory HOT 1
- [Feature Request] `just global init-rust`; an ability to define global `Justfile` that will run commands anywhere on your machine. HOT 2
- Stabilize `[script(…)]` attribute HOT 6
- Comments Ending in Backslash also Comment following Command HOT 2
- Add ability to add new dependency without clobbering rule HOT 6
- Transitive options when using modules
- `just --list` should highlight parts of the comment surrounded by backticks (`) HOT 1
- Set default working dir for the whole justfile HOT 2
- Multiple optional parameters, specifying only one HOT 1
- Command line flag to exit without error if recipe not found HOT 1
- Add missing or (if it's there) improve module information in documentation HOT 1
- Mark recipes as exportable/non-exportable HOT 1
- Warning when compiling with Rust 1.80 HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from just.