about summary refs log tree commit diff
path: root/scripts/nix-pull.in
blob: 6472c7c647768f3ada555f916ee7932f329a98ab (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#! @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 store expressions...\n";
my $pid = open2(\*READ, \*WRITE, "@bindir@/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 "@bindir@/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 "@bindir@/nix-store --successor @sucs2";
    if ($?) { die "`nix-store --successor' failed"; }
}