lix/scripts/nix-pull.in
Eelco Dolstra e7ea52d3b3 * One-click installation :-)
The script nix-install-package takes a `Nix package file' (which
  contains one or more derivations, along with URLs of Nix caches),
  unpacks it, pulls the caches, and installs the derivations in the
  user's environment.

  For best results, associate the command `xterm -e
  /nix/bin/nix-install-package' with the MIME type
  `application/x-nix-package' and visit
  http://losser.st-lab.cs.uu.nl/~eelco/test/.
2003-11-24 11:11:40 +00:00

150 lines
3.6 KiB
Perl

#! /usr/bin/perl -w
use strict;
use IPC::Open2;
use POSIX qw(tmpnam);
my $tmpdir;
do { $tmpdir = tmpnam(); }
until mkdir $tmpdir, 0777;
my $manifest = "$tmpdir/manifest";
my $conffile = "@sysconfdir@/nix/prebuilts.conf";
#END { unlink $manifest; rmdir $tmpdir; }
my @srcpaths;
my @subs;
my @sucs;
my $fullexpr = "[";
sub processURL {
my $url = shift;
$url =~ s/\/$//;
print "obtaining list of Nix archives at $url...\n";
system "wget --cache=off '$url'/MANIFEST -O '$manifest' 2> /dev/null"; # !!! escape
if ($?) { die "`wget' failed"; }
open MANIFEST, "<$manifest";
my $inside = 0;
my $storepath;
my $narname;
my $hash;
my @preds;
while (<MANIFEST>) {
chomp;
s/\#.*$//g;
next if (/^$/);
if (!$inside) {
if (/^\{$/) {
$inside = 1;
undef $storepath;
undef $narname;
undef $hash;
@preds = ();
}
else { die "bad line: $_"; }
} else {
if (/^\}$/) {
$inside = 0;
my $fullurl = "$url/$narname";
# print "$storepath\n";
# Construct a Nix expression that fetches and unpacks a
# Nix archive from the network.
my $fetch =
"(import @datadir@/nix/corepkgs/fetchurl) " .
"{url = $fullurl; md5 = \"$hash\"; system = \"@host@\"}";
my $nixexpr =
"((import @datadir@/nix/corepkgs/nar/unnar.nix) " .
"{narFile = ($fetch); outPath = \"$storepath\"; system = \"@host@\"}) ";
$fullexpr .= $nixexpr; # !!! O(n^2)?
push @srcpaths, $storepath;
foreach my $p (@preds) {
push @sucs, $p;
push @sucs, $storepath;
}
}
elsif (/^\s*StorePath:\s*(\/\S+)\s*$/) {
$storepath = $1;
}
elsif (/^\s*NarName:\s*(\S+)\s*$/) {
$narname = $1;
}
elsif (/^\s*MD5:\s*(\S+)\s*$/) {
$hash = $1;
}
elsif (/^\s*SuccOf:\s*(\/\S+)\s*$/) {
push @preds, $1;
}
else { die "bad line: $_"; }
}
}
close MANIFEST;
}
# Obtain URLs either from the command line or from a configuration file.
if (scalar @ARGV > 0) {
while (@ARGV) {
my $url = shift @ARGV;
processURL $url;
}
} else {
open CONFFILE, "<$conffile";
while (<CONFFILE>) {
chomp;
if (/^\s*(\S+)\s*(\#.*)?$/) {
my $url = $1;
processURL $url;
}
}
close CONFFILE;
}
$fullexpr .= "]";
# Instantiate store expressions from the Nix expressions we created above.
print STDERR "instantiating Nix expression...\n";
my $pid = open2(\*READ, \*WRITE, "nix-instantiate -") or die "cannot run nix-instantiate";
print WRITE $fullexpr;
close WRITE;
my $i = 0;
while (<READ>) {
chomp;
die unless /^\//;
my $subpath = $_;
die unless ($i < scalar @srcpaths);
my $srcpath = $srcpaths[$i++];
push @subs, $srcpath;
push @subs, $subpath;
}
waitpid $pid, 0;
$? == 0 or die "nix-instantiate failed";
# Register all substitutes.
print STDERR "registering substitutes...\n";
system "nix-store --substitute @subs";
if ($?) { die "`nix-store --substitute' failed"; }
# Register all successors.
print STDERR "registering successors...\n";
system "nix-store --successor @sucs";
if ($?) { die "`nix-store --successor' failed"; }