From b76589206a1303fb2dca073f6ec01bc71fc0fab2 Mon Sep 17 00:00:00 2001
From: Eelco Dolstra <eelco.dolstra@logicblox.com>
Date: Thu, 8 Jan 2015 14:56:14 +0100
Subject: [PATCH] nix-shell: Interpret filenames relative to the #!-script
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

So you can have a script like:

  #! /usr/bin/env nix-shell
  #! nix-shell script.nix -i python

  import prettytable

  x = prettytable.PrettyTable(["Foo", "Bar"])
  for i in range(1, 10): x.add_row([i, i**2])
  print x

with a ‘script.nix’ in the same directory:

  with import <nixpkgs> {};

  runCommand "dummy" { buildInputs = [ python pythonPackages.prettytable ]; } ""

(Of course, in this particular case, using the ‘-p’ flag is more
convenient.)
---
 scripts/nix-build.in | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/scripts/nix-build.in b/scripts/nix-build.in
index b7c923f88..12826323c 100755
--- a/scripts/nix-build.in
+++ b/scripts/nix-build.in
@@ -5,6 +5,8 @@ use strict;
 use Nix::Config;
 use Nix::Store;
 use Nix::Utils;
+use File::Basename;
+use Cwd;
 
 binmode STDERR, ":encoding(utf8)";
 
@@ -219,6 +221,11 @@ foreach my $expr (@exprs) {
     # Instantiate.
     my @drvPaths;
     if ($expr !~ /^\/.*\.drv$/) {
+        # If we're in a #! script, interpret filenames relative to the
+        # script.
+        $expr = dirname(Cwd::abs_path($script)) . "/" . $expr
+            if $inShebang && $expr !~ /^\//;
+
         # !!! would prefer the perl 5.8.0 pipe open feature here.
         my $pid = open(DRVPATHS, "-|") || exec "$Nix::Config::binDir/nix-instantiate", "--add-root", $drvLink, "--indirect", @instArgs, $expr;
         while (<DRVPATHS>) {chomp; push @drvPaths, $_;}
-- 
GitLab