Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New Shebang #1256

Closed
runeimp opened this issue Jun 30, 2022 · 8 comments
Closed

New Shebang #1256

runeimp opened this issue Jun 30, 2022 · 8 comments

Comments

@runeimp
Copy link

runeimp commented Jun 30, 2022

I'd like to use PowerShell as the only shell and scripting language in Just as it is available on Linux and Mac as well as Windows. The one thing that kills that is the shebang. The traditional shebang requires a full path to the executable. For many languages you would just have #!/usr/bin/env interpreter but /usr/bin/env or even env does not exist on Windows. I need the ability to tell Just that the recipe is a script without using a shebang. I also don't desire to use or expect and can use \ at the end of lines to continue some gargantuan one-liner in this context. A possible solution would be allowing #!default as the shebang to trigger the default shell (in this case set shell := ["pwsh", "-NoLogo", "-Command"]) in scripting mode. I apologize if that is already a feature in some fashion and missed it.

@casey
Copy link
Owner

casey commented Jul 1, 2022

Hmm, can you use #!pwsh.exe or #!powershell.exe, or does that not work?

I think the best way to support this would be via an annotation:

[script]
foo:

@runeimp
Copy link
Author

runeimp commented Jul 2, 2022

I have no idea how you get shebang to work on Windows at all when there is no sh.exe available. Does PowerShell support Shebang natively? Your example #!pwsh.exe or even #!pwsh works on Windows but neither works on *nix. At least not on macOS and I would expect the same for all variations of Unix and GNU/Linux.

The annotation sounds like a good option. Especially if the shebang is not handled special by Just before execution on anything other than Windows. I also wouldn't mind #! as a recipe label prefix to denote it's a shebang script base recipe. Such as

#!recipe:
    Awesome script code
    goes here

That could be called with just recipe. I'm guessing neither options is going work swimmingly with Make based themes for code editors. But that's never perfect anyway.

@casey
Copy link
Owner

casey commented Jul 3, 2022

On Windows, just actually parses shebang lines itself.

Your example #!pwsh.exe or even #!pwsh works on Windows but neither works on *nix. At least not on macOS and I would expect the same for all variations of Unix and GNU/Linux.

Is there any way to get this to work? On MacOS I was able to create and execute the following script:

#!python3
print('foo')

@runeimp
Copy link
Author

runeimp commented Jul 7, 2022

Huh? Did you put that in a script file or in a Justfile recipe? Also what version of macOS is that and with which shell? I tried that code in both and got bash: ./script: python3: bad interpreter: No such file or directory for the script and error: Recipe `python` with shebang `#!python3` execution error: No such file or directory (os error 2) for the recipe. Neither works for me unless I put the full path

#!/usr/local/bin/python3
print('foo')

This is on macOS Big Sur using Bash, Zsh, or PowerShell, and has always been the case for me since OS X Tiger.

@casey
Copy link
Owner

casey commented Jul 8, 2022

Ahh, okay, it for me in a script, but not a justfile, so maybe my shell (zsh) is doing some special magic to make it work.

Okay, here's a more complete sketch for how this could work. Recipes with the script annotation are executed as scripts, like shebang recipes, but instead of being executed directly, and relying on the OS to interpret the shebang line to run the script, a script-interpreter (or script-runner, not sure) setting, controls the command that executes the script. The setting takes an list, which is the binary, plus any arguments, to invoke, and it receives the script as the final argument.

# this recipe will be executed as a script using the default script-runner, `sh`
[script]
foo:
  echo bar
set script-runner := ["pwsh.exe"]

# this recipe will be executed as a script using pwsh.exe
[script]
foo:
  echo bar

What do you think?

@runeimp
Copy link
Author

runeimp commented Jul 8, 2022

Yeah, it's probably something that is part of Oh My Zsh if you're using that. I haven't got that in my Zsh setup.

Other than that, sounds good to me! 😁

@AceofSpades5757
Copy link

AceofSpades5757 commented Aug 24, 2022

I think this answers the original question. Although I was really hoping to use a conditional when using set shell, but it kept giving me syntax errors.

SHEBANG := if os_family() == "windows" { "powershell.exe" } else { "/usr/bin/env pwsh" }

echo:
	#!{{ SHEBANG }}
	echo $PSVersionTable

Tested on Windows and Ubuntu (WSL) using different PowerShell versions.

@runeimp
Copy link
Author

runeimp commented Sep 8, 2022

Hey @AceofSpades5757 that's what we worked out in #1293. Great minds think alike! 😃

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants