about summary refs log tree commit diff
path: root/scripts/nix-install-package.in
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/nix-install-package.in')
-rwxr-xr-xscripts/nix-install-package.in138
1 files changed, 138 insertions, 0 deletions
diff --git a/scripts/nix-install-package.in b/scripts/nix-install-package.in
new file mode 100755
index 000000000000..e45337bcc9e5
--- /dev/null
+++ b/scripts/nix-install-package.in
@@ -0,0 +1,138 @@
+#! @perl@ -w @perlFlags@
+
+use strict;
+use File::Temp qw(tempdir);
+use Nix::Config;
+use Nix::Utils;
+
+
+# Parse the command line arguments.
+my @args = @ARGV;
+
+my $source;
+my $fromURL = 0;
+my @extraNixEnvArgs = ();
+my $interactive = 1;
+
+while (scalar @args) {
+    my $arg = shift @args;
+    if ($arg eq "--help") {
+        exec "man nix-install-package" or die;
+    }
+    elsif ($arg eq "--url") {
+        $fromURL = 1;
+    }
+    elsif ($arg eq "--profile" || $arg eq "-p") {
+        my $profile = shift @args;
+        die "$0: `--profile' requires an argument\n" if !defined $profile;
+        push @extraNixEnvArgs, "-p", $profile;
+    }
+    elsif ($arg eq "--non-interactive") {
+        $interactive = 0;
+    }
+    else {
+        $source = $arg;
+    }
+}
+
+die "$0: please specify a .nixpkg file or URL\n" unless defined $source;
+
+
+# Re-execute in a terminal, if necessary, so that if we're executed
+# from a web browser, the user gets to see us.
+if ($interactive && !defined $ENV{"NIX_HAVE_TERMINAL"}) {
+    $ENV{"NIX_HAVE_TERMINAL"} = "1";
+    $ENV{"LD_LIBRARY_PATH"} = "";
+    foreach my $term ("xterm", "konsole", "gnome-terminal", "xterm") {
+        exec($term, "-e", "$Nix::Config::binDir/nix-install-package", @ARGV);
+    }
+    die "cannot execute `xterm'";
+}
+
+
+my $tmpDir = tempdir("nix-install-package.XXXXXX", CLEANUP => 1, TMPDIR => 1)
+    or die "cannot create a temporary directory";
+
+
+sub barf {
+    my $msg = shift;
+    print "\nInstallation failed: $msg\n";
+    <STDIN> if $interactive;
+    exit 1;
+}
+
+
+# Download the package description, if necessary.
+my $pkgFile = $source;
+if ($fromURL) {
+    $pkgFile = "$tmpDir/tmp.nixpkg";
+    system("@curl@", "--silent", $source, "-o", $pkgFile) == 0
+        or barf "curl failed: $?";
+}
+
+
+# Read and parse the package file.
+open PKGFILE, "<$pkgFile" or barf "cannot open `$pkgFile': $!";
+my $contents = <PKGFILE>;
+close PKGFILE;
+
+my $nameRE = "(?: [A-Za-z0-9\+\-\.\_\?\=]+ )"; # see checkStoreName()
+my $systemRE = "(?: [A-Za-z0-9\+\-\_]+ )";
+my $pathRE = "(?: \/ [\/A-Za-z0-9\+\-\.\_\?\=]* )";
+
+# Note: $pathRE doesn't check that whether we're looking at a valid
+# store path.  We'll let nix-env do that.
+
+$contents =~
+    / ^ \s* (\S+) \s+ ($Nix::Utils::urlRE) \s+ ($nameRE) \s+ ($systemRE) \s+ ($pathRE) \s+ ($pathRE) ( \s+ ($Nix::Utils::urlRE) )?  /x
+    or barf "invalid package contents";
+my $version = $1;
+my $manifestURL = $2;
+my $drvName = $3;
+my $system = $4;
+my $drvPath = $5;
+my $outPath = $6;
+my $binaryCacheURL = $8;
+
+barf "invalid package version `$version'" unless $version eq "NIXPKG1";
+
+
+if ($interactive) {
+    # Ask confirmation.
+    print "Do you want to install `$drvName' (Y/N)? ";
+    my $reply = <STDIN>;
+    chomp $reply;
+    exit if $reply ne "y" && $reply ne "Y";
+}
+
+
+if (defined $binaryCacheURL) {
+
+    push @extraNixEnvArgs, "--option", "binary-caches", $binaryCacheURL;
+
+} else {
+
+    # Store the manifest in the temporary directory so that we don't
+    # pollute /nix/var/nix/manifests.  This also requires that we
+    # don't use the Nix daemon (because otherwise
+    # download-using-manifests won't see our NIX_MANIFESTS_DIRS
+    # environment variable).
+    $ENV{NIX_MANIFESTS_DIR} = $tmpDir;
+    $ENV{NIX_REMOTE} = "";
+
+    print "\nPulling manifests...\n";
+    system("$Nix::Config::binDir/nix-pull", $manifestURL) == 0
+        or barf "nix-pull failed: $?";
+
+}
+
+
+print "\nInstalling package...\n";
+system("$Nix::Config::binDir/nix-env", "--install", $outPath, "--force-name", $drvName, @extraNixEnvArgs) == 0
+    or barf "nix-env failed: $?";
+
+
+if ($interactive) {
+    print "\nInstallation succeeded! Press Enter to continue.\n";
+    <STDIN>;
+}