From 06c5a7075d85636ba1fedce1fc5b131cdcffd5f8 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 5 Dec 2003 11:25:38 +0000 Subject: [PATCH] * Refactoring: put the manifest-reading code in a separate file. --- scripts/Makefile.am | 8 ++- scripts/nix-pull.in | 124 +++++++++++-------------------------- scripts/readmanifest.pm.in | 72 +++++++++++++++++++++ 3 files changed, 114 insertions(+), 90 deletions(-) create mode 100644 scripts/readmanifest.pm.in diff --git a/scripts/Makefile.am b/scripts/Makefile.am index 94df32b24..1662e99c1 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -4,9 +4,13 @@ bin_SCRIPTS = nix-collect-garbage \ noinst_SCRIPTS = nix-profile.sh -install-exec-local: +nix-pull nix-push: readmanifest.pm + +install-exec-local: readmanifest.pm $(INSTALL) -d $(sysconfdir)/profile.d $(INSTALL_PROGRAM) nix-profile.sh $(sysconfdir)/profile.d/nix.sh + $(INSTALL) -d $(libexecdir)/nix + $(INSTALL_DATA) readmanifest.pm $(libexecdir)/nix $(INSTALL) -d $(sysconfdir)/nix # !!! don't overwrite local modifications $(INSTALL_DATA) prebuilts.conf $(sysconfdir)/nix/prebuilts.conf @@ -16,5 +20,5 @@ include ../substitute.mk EXTRA_DIST = nix-collect-garbage.in \ nix-pull.in nix-push.in nix-profile.sh.in \ nix-prefetch-url.in nix-install-package.in \ - prebuilts.conf + prebuilts.conf readmanifest.pm diff --git a/scripts/nix-pull.in b/scripts/nix-pull.in index 86004102d..040ee54c9 100644 --- a/scripts/nix-pull.in +++ b/scripts/nix-pull.in @@ -1,8 +1,9 @@ -#! /usr/bin/perl -w +#! /usr/bin/perl -w -I@libexecdir@/nix use strict; use IPC::Open2; use POSIX qw(tmpnam); +use readmanifest; my $tmpdir; do { $tmpdir = tmpnam(); } @@ -13,93 +14,19 @@ 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 () { - 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 = \"@system@\"}"; - my $nixexpr = - "((import @datadir@/nix/corepkgs/nar/unnar.nix) " . - "{narFile = ($fetch); outPath = \"$storepath\"; system = \"@system@\"}) "; - $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. +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; - processURL $url; + doURL $url; } } else { open CONFFILE, "<$conffile"; @@ -107,12 +34,32 @@ if (scalar @ARGV > 0) { chomp; if (/^\s*(\S+)\s*(\#.*)?$/) { my $url = $1; - processURL $url; + 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 .= "]"; @@ -123,14 +70,13 @@ my $pid = open2(\*READ, \*WRITE, "nix-instantiate -") or die "cannot run nix-ins print WRITE $fullexpr; close WRITE; my $i = 0; +my %substitutes; while () { chomp; die unless /^\//; my $subpath = $_; - die unless ($i < scalar @srcpaths); - my $srcpath = $srcpaths[$i++]; - push @subs, $srcpath; - push @subs, $subpath; + die unless ($i < scalar @storepaths); + $substitutes{$storepaths[$i++]} = $subpath; } waitpid $pid, 0; @@ -139,6 +85,7 @@ $? == 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 }; @@ -151,6 +98,7 @@ while (scalar @subs > 0) { # Register all successors. print STDERR "registering successors...\n"; +my @sucs = %successors; while (scalar @sucs > 0) { my $n = scalar @sucs; if ($n > 256) { $n = 256 }; diff --git a/scripts/readmanifest.pm.in b/scripts/readmanifest.pm.in new file mode 100644 index 000000000..e8819d8b8 --- /dev/null +++ b/scripts/readmanifest.pm.in @@ -0,0 +1,72 @@ +use strict; + +sub processURL { + my $manifest = shift; + my $url = shift; + my $storepaths2urls = shift; + my $urls2hashes = shift; + my $successors = 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 () { + 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"; + + $$storepaths2urls{$storepath} = $fullurl; + $$urls2hashes{$fullurl} = $hash; + + foreach my $p (@preds) { + $$successors{$p} = $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; +} + + +return 1;