diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/fix.cc | 40 | ||||
-rwxr-xr-x | src/nix-populate | 89 |
2 files changed, 28 insertions, 101 deletions
diff --git a/src/fix.cc b/src/fix.cc index bf335bc365b6..8d5cc6bf8e0b 100644 --- a/src/fix.cc +++ b/src/fix.cc @@ -2,6 +2,7 @@ #include <map> #include <sys/types.h> +#include <sys/stat.h> #include <sys/wait.h> extern "C" { @@ -15,9 +16,17 @@ static string nixDescriptorDir; static string nixSourcesDir; +/* Mapping of Fix file names to the hashes of the resulting Nix + descriptors. */ typedef map<string, string> DescriptorMap; +/* Forward declarations. */ + +string instantiateDescriptor(string filename, + DescriptorMap & done); + + void registerFile(string filename) { int res = system(("nix regfile " + filename).c_str()); @@ -52,12 +61,15 @@ string fetchURL(string url) { string filename = baseNameOf(url); string fullname = nixSourcesDir + "/" + filename; - /* !!! quoting */ - string shellCmd = - "cd " + nixSourcesDir + " && wget --quiet -N \"" + url + "\""; - int res = system(shellCmd.c_str()); - if (WEXITSTATUS(res) != 0) - throw Error("cannot fetch " + url); + struct stat st; + if (stat(fullname.c_str(), &st)) { + /* !!! quoting */ + string shellCmd = + "cd " + nixSourcesDir + " && wget --quiet -N \"" + url + "\""; + int res = system(shellCmd.c_str()); + if (WEXITSTATUS(res) != 0) + throw Error("cannot fetch " + url); + } return fullname; } @@ -101,17 +113,21 @@ string evaluateFile(ATerm e, string dir) throw Error("cannot copy " + filename); registerFile(nixSourcesDir + "/" + baseNameOf(filename)); return hashFile(filename); - } else throw Error("invalid hash expression"); + } else throw Error("invalid file expression"); } -string evaluatePkg(ATerm e, DescriptorMap & done) +string evaluatePkg(ATerm e, string dir, DescriptorMap & done) { char * s; + ATerm t; if (ATmatch(e, "<str>", &s)) { checkHash(s); return s; - } else throw Error("invalid hash expression"); + } else if (ATmatch(e, "Fix(<term>)", &t)) { + string filename = absPath(evaluateStr(t), dir); /* !!! */ + return instantiateDescriptor(filename, done); + } else throw Error("invalid pkg expression"); } @@ -125,7 +141,7 @@ ATerm evaluate(ATerm e, string dir, DescriptorMap & done) else if (ATmatch(e, "File(<term>)", &t)) return ATmake("File(<str>)", evaluateFile(t, dir).c_str()); else if (ATmatch(e, "Pkg(<term>)", &t)) - return ATmake("Pkg(<str>)", evaluatePkg(t, done).c_str()); + return ATmake("Pkg(<str>)", evaluatePkg(t, dir, done).c_str()); else throw Error("invalid expression type"); } @@ -215,8 +231,8 @@ string instantiateDescriptor(string filename, /* Register it with Nix. */ registerFile(outFilename); - done[filename] = outFilename; - return outFilename; + done[filename] = outHash; + return outHash; } diff --git a/src/nix-populate b/src/nix-populate deleted file mode 100755 index 50819d6664d4..000000000000 --- a/src/nix-populate +++ /dev/null @@ -1,89 +0,0 @@ -#! /usr/bin/perl -w - -use strict; - -my $pkglist = $ENV{"NIX_ACTIVATIONS"}; -$pkglist or die "NIX_ACTIVATIONS not set"; -my $linkdir = $ENV{"NIX_LINKS"}; -$linkdir or die "NIX_LINKS not set"; -my @dirs = ("bin", "sbin", "lib", "include"); - -# Figure out a generation number. -my $nr = 1; -while (-e "$linkdir/$nr") { $nr++; } -my $gendir = "$linkdir/$nr"; -print "populating $gendir\n"; - -# Create the subdirectories. -mkdir $gendir; -foreach my $dir (@dirs) { - mkdir "$gendir/$dir"; -} - -# For each activated package, create symlinks. - -sub createLinks { - my $srcdir = shift; - my $dstdir = shift; - - my @srcfiles = glob("$srcdir/*"); - - foreach my $srcfile (@srcfiles) { - my $basename = $srcfile; - $basename =~ s/^.*\///g; # strip directory - my $dstfile = "$dstdir/$basename"; - if (-d $srcfile) { - # !!! hack for resolving name clashes - if (!-e $dstfile) { - mkdir($dstfile) or - die "error creating directory $dstfile"; - } - -d $dstfile or die "$dstfile is not a directory"; - createLinks($srcfile, $dstfile); - } elsif (-l $dstfile) { - my $target = readlink($dstfile); - die "collission between $srcfile and $target"; - } else { - print "linking $dstfile to $srcfile\n"; - symlink($srcfile, $dstfile) or - die "error creating link $dstfile"; - } - } -} - - -open PKGS, "< $pkglist"; - -while (<PKGS>) { - chomp; - my $hash = $_; - - my $pkgdir = `nix getpkg $hash`; - if ($?) { die "`nix getpkg' failed"; } - chomp $pkgdir; - - print "merging $pkgdir\n"; - - foreach my $dir (@dirs) { - createLinks("$pkgdir/$dir", "$gendir/$dir"); - } -} - -close PKGS; - -# Make $gendir the current generation by pointing $linkdir/current to -# it. The rename() system call is supposed to be essentially atomic -# on Unix. That is, if we have links `current -> X' and `new_current -# -> Y', and we rename new_current to current, a process accessing -# current will see X or Y, but never a file-not-found or other error -# condition. This is sufficient to atomically switch the current link -# tree. - -my $current = "$linkdir/current"; - -print "switching $current to $gendir\n"; - -my $tmplink = "$linkdir/new_current"; -symlink($gendir, $tmplink) or die "cannot create $tmplink"; -rename($tmplink, $current) or die "cannot rename $tmplink"; - |