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

                   
           
               
                     
 




                                  
                                                 
 


                                         
         
         
 
                   
 






                                 
                        


                                                            
                                                                                           

                                        

                                    
                       
 



                      

                            


















                                                  
                                                                           

                                                   





                                                                                                






















                                                        

         
                       


     
 
                 
 
 


                                                                                          


                      
          
                
          





                                       

 
                
                                        
 
 

                                            

                                                  
 
 

                                           

                                                 
#! /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 = "[";

open CONFFILE, "<$conffile";

while (<CONFFILE>) {

    chomp;
    if (/^\s*(\S+)\s*(\#.*)?$/) {
        my $url = $1;
        $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;
    }

}

$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"; }