diff options
Diffstat (limited to 'scripts/nix-install-package.in')
-rwxr-xr-x | scripts/nix-install-package.in | 138 |
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>; +} |