google / zx

A tool for writing better scripts
https://google.github.io/zx/
Apache License 2.0
43.07k stars 1.1k forks source link

Allow multiple lines of hashbangs #715

Open fmnxl opened 9 months ago

fmnxl commented 9 months ago

Expected Behavior

Nix allows the use of shebang to define a custom interpreter, for example:

#! /usr/bin/env nix-shell
#! nix-shell -i zx -p zx

await $`echo 1`

zx should ignore multiple shebang lines instead only the first one.

Actual Behavior

SyntaxError: Invalid or unexpected token

Steps to Reproduce the Problem

  1. (setup) Install nix
  2. Add the above shebang lines to the start of the script (script.mjs)
  3. Try to run the script with zx script.mjs

Specifications

jlbribeiro commented 2 months ago

@fmnxl (also cc @rockofox), and anyone interested: this issue keeps bugging me, probably for the same reason as you, nix-shell (so we can use zx in a "fully contained" way). Given both #715 and #716 got closed without this being addressed, using "two shebangs" still results in a SyntaxError.

As I managed to find a different not-as-portable approach to overcome this limitation (which makes it a single shebang line), I'm sharing it here. Afaict, it requires two things:

If you can live with those two requirements, this is the shebang line:

#!/usr/bin/env -S nix shell nixpkgs#zx --command zx

Please let me know if this works for you, and if you manage to find a way to simplify this.

(given the current files-without-extension temporary files behavior, I advise you to still use the .mjs extension for now, unfortunately.)

antonmedv commented 2 months ago

Actually shbang supported via node. Zx not handles shbang.

antongolub commented 1 month ago

Hmm... https://stackoverflow.com/questions/12910744/why-should-the-shebang-line-always-be-the-first-line

jlbribeiro commented 1 month ago

@antonmedv I guess the reasoning behind this issue being a feature request was because it was possible for zx to be hackishly modified to support them (as implemented in #716).

@fmnxl @rockofox I just accidentally discovered that nix-shell parses nix-shell option hashbangs anywhere in the file. This was discussed in https://github.com/NixOS/nix/issues/2570 and finally documented in https://github.com/NixOS/nix/pull/11202 (so the first reference to this in documentation appears in the 2.24 docs (last paragraph)).

As such, @antonmedv, I believe this issue can be closed because, as in the unofficial NixOS wiki Lua example, we can resort to JavaScript's block comments ("multi-line") to make this work with nix-shell:

#! /usr/bin/env nix-shell
/*
#! nix-shell -i zx -p zx
*/

$.verbose = true;

await Promise.all([
  $`sleep 1; echo 1`,
  $`sleep 2; echo 2`,
  $`sleep 3; echo 3`,
]);
antonmedv commented 1 month ago

Should we add some notes about this behavior to documentation? A nix-guide of docs website?

@jlbribeiro maybe you can write a short .md file?