lix/scripts/nix-install-package.in
2015-01-30 11:30:21 +01:00

144 lines
3.6 KiB
Plaintext
Executable file
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#! @perl@ -w @perlFlags@
use utf8;
use strict;
use Nix::Config;
use Nix::Utils;
binmode STDERR, ":encoding(utf8)";
# Parse the command line arguments.
my @args = @ARGV;
my $source;
my $fromURL = 0;
my @extraNixEnvArgs = ();
my $interactive = 1;
my $op = "--install";
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 "--set") {
$op = "--set";
}
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 = mkTempDir("nix-install-package");
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@", "-L", "--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", "extra-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", $op, $outPath, "--force-name", $drvName, @extraNixEnvArgs) == 0
or barf "nix-env failed: $?";
if ($interactive) {
print "\nInstallation succeeded! Press Enter to continue.\n";
<STDIN>;
}