about summary refs log blame commit diff
path: root/scripts/nix-pull.in
blob: 40e7d62f3a20a3d954739c91632878a27503ace6 (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 = "[";
my $first = 1;

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 Fix expression that fetches and unpacks a
		    # Nix archive from the network.
		    my $fetch =
			"App(IncludeFix(\"fetchurl/fetchurl.fix\"), " .
			"[(\"url\", \"$fullurl\"), (\"md5\", \"$hash\")])";
		    my $fixexpr = 
			"App(IncludeFix(\"nar/unnar.fix\"), " .
			"[ (\"nar\", $fetch)" .
			", (\"outPath\", \"$storepath\")" .
			"])";
		    
		    if (!$first) { $fullexpr .= "," };
		    $first = 0;
		    $fullexpr .= $fixexpr; # !!! 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 Nix expressions from the Fix expressions we created above.
print STDERR "running fix...\n";
my $pid = open2(\*READ, \*WRITE, "fix -") or die "cannot run fix";

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 "fix failed";


# Register all substitutes.
print STDERR "registering substitutes...\n";
system "nix --substitute @subs";
if ($?) { die "`nix --substitute' failed"; }


# Register all successors.
print STDERR "registering successors...\n";
system "nix --successor @sucs";
if ($?) { die "`nix --successor' failed"; }