about summary refs log blame commit diff
path: root/scripts/nix-pull.in
blob: 040ee54c9d2ae5864f1163fe8a26864c3c782c1b (plain) (tree)
1
2
3
4
5
6
7
                                      
 
           
               
                     
                 
 




                                  
                                                 
 

                                         
 




                                                                        
                    
                                                                               
 


                              
                   






                                     
                       


                   
 
 



















                                                                                  
                 
 
 


                                                                                          


                      
          
                
                
          

                     

                                               

 
                
                                        
 
 

                                            
                        







                                                      
 
 

                                           
                       







                                                     
#! /usr/bin/perl -w -I@libexecdir@/nix

use strict;
use IPC::Open2;
use POSIX qw(tmpnam);
use readmanifest;

my $tmpdir;
do { $tmpdir = tmpnam(); }
until mkdir $tmpdir, 0777;

my $manifest = "$tmpdir/manifest";
my $conffile = "@sysconfdir@/nix/prebuilts.conf";

#END { unlink $manifest; rmdir $tmpdir; }


# Obtain URLs either from the command line or from a configuration file.
my %storepaths2urls;
my %urls2hashes;
my %successors;
sub doURL {
    my $url = shift;
    processURL $manifest, $url, \%storepaths2urls, \%urls2hashes, \%successors;
}
if (scalar @ARGV > 0) {
    while (@ARGV) {
        my $url = shift @ARGV;
	doURL $url;
    }
} else {
    open CONFFILE, "<$conffile";
    while (<CONFFILE>) {
        chomp;
        if (/^\s*(\S+)\s*(\#.*)?$/) {
            my $url = $1;
	    doURL $url;
        }
    }
    close CONFFILE;
}


# Create a Nix expression for the substitutes.
my $fullexpr = "[";

my @storepaths;
foreach my $storepath (keys %storepaths2urls) {
    # Construct a Nix expression that fetches and unpacks a
    # Nix archive from the network.
    my $url = $storepaths2urls{$storepath};
    my $hash = $urls2hashes{$url};
    my $fetch =
	"(import @datadir@/nix/corepkgs/fetchurl) " .
	"{url = $url; md5 = \"$hash\"; system = \"@system@\"}";
    my $nixexpr =
	"((import @datadir@/nix/corepkgs/nar/unnar.nix) " .
	"{narFile = ($fetch); outPath = \"$storepath\"; system = \"@system@\"}) ";
    $fullexpr .= $nixexpr; # !!! O(n^2)?
    push @storepaths, $storepath;
}

$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;
my %substitutes;
while (<READ>) {
    chomp;
    die unless /^\//;
    my $subpath = $_;
    die unless ($i < scalar @storepaths);
    $substitutes{$storepaths[$i++]} = $subpath;
}

waitpid $pid, 0;
$? == 0 or die "nix-instantiate failed";


# Register all substitutes.
print STDERR "registering substitutes...\n";
my @subs = %substitutes;
while (scalar @subs > 0) {
    my $n = scalar @subs;
    if ($n > 256) { $n = 256 };
    my @subs2 = @subs[0..$n - 1];
    @subs = @subs[$n..scalar @subs - 1];
    system "nix-store --substitute @subs2";
    if ($?) { die "`nix-store --substitute' failed"; }
}


# Register all successors.
print STDERR "registering successors...\n";
my @sucs = %successors;
while (scalar @sucs > 0) {
    my $n = scalar @sucs;
    if ($n > 256) { $n = 256 };
    my @sucs2 = @sucs[0..$n - 1];
    @sucs = @sucs[$n..scalar @sucs - 1];
    system "nix-store --successor @sucs";
    if ($?) { die "`nix-store --successor' failed"; }
}