NixOS / nix

Nix, the purely functional package manager
https://nixos.org/
GNU Lesser General Public License v2.1
12.26k stars 1.48k forks source link

Can't use nix-shell as a script interpreter for Lua programs, perhaps others. #604

Open fmap opened 9 years ago

fmap commented 9 years ago

http://nixos.org/nix/manual/#ssec-nix-shell-shebang:

You can use nix-shell as a script interpreter to allow scripts written in arbitrary languages to obtain their own dependencies via Nix. This is done by starting the script with the following lines:

#! /usr/bin/env nix-shell
#! nix-shell -i real-interpreter -p packages

[..]

The lines starting with #! nix-shell specify nix-shell options (see above). Note that you cannot write #1 /usr/bin/env nix-shell -i ... because /usr/bin/env does not support passing options to the interpreter.

This hack falls down when targeting real interpreters in which both (1) multiple shebang lines aren't admitted and (2) in which #s don't indicate the start of a comment. This is true of at least Lua:

% cat > test; chmod +x test 
#! /nix/store/c7axvzpsf10a6z90a1qggcz9d9ll0h0i-lua-5.3.0/bin/lua
print "Hello, world!"
% ./test
Hello, world! 
% cat > test
#! /nix/store/gfv9nfgz66hcd9m1f83w2c6wzvqf70ww-nix-1.10pre1234_abcdef/bin/nix-shell
#! nix-shell -i lua -p lua
print "Hello, world!"
% ./test
lua: ./test:2: unexpected symbol near '#'

One workaround might be to remove shebang lines before passing off scripts to their target interpreters, writing out modified scripts to temporary files. Overriding the zeroth argument with exec -a (as in the existing Perl "Überhack") should keep the environment fairly sane, and I don't see any good reasons for other interpreters to process nix-shell directives. Before I try working up a patch, thoughts?

fmap commented 9 years ago

Closing due to lack of interest.

vcunat commented 9 years ago

IMO such enhancement wishes can be kept open, as long as they are still meaningful.

copumpkin commented 9 years ago

Agreed. People are busy and lots of people want lots of different things, but it doesn't mean these things aren't important.

fmap commented 9 years ago

Fair.

tomjridge commented 8 years ago

I have the same problem with scala. The following doesn't work unfortunately:

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

object Test {

  def main(args:Array[String]) {
    println("Hello world!")
  }

}
tomjridge commented 8 years ago

Any suggested workarounds?

cessationoftime commented 7 years ago

this works for scala, it strips the bash portion of the file and places the rest in a temp file and then feeds that to scala:

#! /usr/bin/env nix-shell
#! nix-shell -i bash -p scala

tmp=mktemp
cat "$0" | tail +8 > $tmp
exec scala "$tmp" "$@"
!#
object Main extends App {
  import scala.sys.process._
  val cmd = "ls -l" // Your command
  val output = cmd.!! // Captures the output
  println(output)
  println("Hello World: " + (args mkString ", "))
}

For Scala, using Ammonite for scripts would be a better choice, see: https://github.com/lihaoyi/Ammonite/pull/686

#! /usr/bin/env nix-shell
#! nix-shell -i amm -p ammonite-repl
!#

import scala.sys.process._
val cmd = "ls -l" // Your command
val output = cmd.!! // Captures the output
println(output)
println("Hello World")
zarybnicky commented 5 years ago

NodeJS has the same problem, execution fails with a SyntaxError on the following:

#! /usr/bin/env nix-shell
#! nix-shell -i node -p nodejs
console.log('ok');

Looking through the logic in Nix source: https://github.com/NixOS/nix/blob/a0ef21262f4d5652bfb65cfacaec01d89c475a93/src/nix-build/nix-build.cc#L109-L128 It seems it's possible to work around the problem by commenting out the next shebang line in whichever way the language requires (Node has special-case rules for the first line), and to write the following, which works:

#! /usr/bin/env nix-shell
/*
#! nix-shell -i node -p nodejs
*/
console.log('ok');
stale[bot] commented 3 years ago

I marked this as stale due to inactivity. → More info

stale[bot] commented 2 years ago

I closed this issue due to inactivity. → More info