2006-01-12 15:17:51 +00:00
|
|
|
#! @perl@ -w
|
|
|
|
|
|
|
|
# This tool unpacks the closures created by "nix-pack-closure" and
|
|
|
|
# adds them to the Nix store.
|
|
|
|
|
|
|
|
# TODO: make this program "streamy", i.e., don't use a temporary
|
|
|
|
# directory.
|
|
|
|
|
|
|
|
use strict;
|
2006-10-04 18:58:11 +00:00
|
|
|
use File::Temp qw(tempdir);
|
2006-01-12 15:17:51 +00:00
|
|
|
|
|
|
|
my $binDir = $ENV{"NIX_BIN_DIR"};
|
|
|
|
$binDir = "@bindir@" unless defined $binDir;
|
|
|
|
|
2006-10-04 18:58:11 +00:00
|
|
|
my $tmpDir = tempdir("nix-unpack-closure.XXXXXX", CLEANUP => 1, TMPDIR => 1)
|
|
|
|
or die "cannot create a temporary directory";
|
2006-01-12 15:17:51 +00:00
|
|
|
|
|
|
|
|
|
|
|
# Unpack the NAR archive on standard input.
|
|
|
|
system("nix-store --restore '$tmpDir/unpacked'") == 0
|
|
|
|
or die "nix-store --restore failed";
|
|
|
|
|
|
|
|
|
|
|
|
open VALID, ">$tmpDir/validity" or die;
|
|
|
|
|
|
|
|
|
|
|
|
# For each path in the closure that is not yet valid, add it to the
|
|
|
|
# store. TODO: use proper locking. Or even better, let nix-store do
|
|
|
|
# this.
|
|
|
|
opendir(DIR, "$tmpDir/unpacked/contents") or die "cannot open directory: $!";
|
|
|
|
|
|
|
|
foreach my $name (sort(readdir DIR)) {
|
|
|
|
next if $name eq "." or $name eq "..";
|
|
|
|
|
2006-09-20 16:23:14 +00:00
|
|
|
my $storePath = "@storedir@/$name"; # !!!
|
2006-01-12 15:17:51 +00:00
|
|
|
|
|
|
|
# !!! this really isn't a good validity check!
|
2006-09-20 16:23:14 +00:00
|
|
|
system "$binDir/nix-store --check-validity '$storePath' 2> /dev/null";
|
2006-01-12 15:17:51 +00:00
|
|
|
if ($? != 0) {
|
|
|
|
print STDERR "unpacking `$storePath'...\n";
|
|
|
|
|
|
|
|
# !!! race
|
2006-09-20 16:23:14 +00:00
|
|
|
system("@coreutils@/rm -rf '$storePath'") == 0
|
2006-01-12 15:17:51 +00:00
|
|
|
or die "cannot remove `$storePath': $?";
|
|
|
|
|
|
|
|
system("$binDir/nix-store --restore '$storePath' < '$tmpDir/unpacked/contents/$name'") == 0
|
|
|
|
or die "nix-store --dump failed on `$storePath': $?";
|
|
|
|
|
|
|
|
print VALID "$storePath\n";
|
|
|
|
|
|
|
|
open DRV, "<$tmpDir/unpacked/derivers/$name" or die;
|
|
|
|
my $deriver = <DRV>;
|
|
|
|
chomp $deriver;
|
|
|
|
$deriver = "" if $deriver eq "unknown-deriver";
|
|
|
|
close DRV;
|
|
|
|
|
|
|
|
my @refs;
|
|
|
|
open REFS, "<$tmpDir/unpacked/references/$name" or die;
|
|
|
|
while (<REFS>) {
|
|
|
|
chomp;
|
|
|
|
push @refs, $_;
|
|
|
|
}
|
|
|
|
close REFS;
|
|
|
|
|
|
|
|
print VALID "$deriver\n";
|
|
|
|
|
|
|
|
print VALID (scalar @refs), "\n";
|
|
|
|
foreach my $ref (@refs) {
|
|
|
|
print VALID "$ref\n";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
closedir(DIR) or die;
|
|
|
|
|
|
|
|
|
|
|
|
# Register the invalid paths as valid.
|
|
|
|
system("nix-store --register-validity <'$tmpDir/validity'") == 0
|
|
|
|
or die "nix-store --register-validity failed";
|
2007-01-13 19:50:42 +00:00
|
|
|
|
|
|
|
|
|
|
|
# Show the top-level paths so that something useful can be done with
|
|
|
|
# them, e.g., passing them to `nix-env -i'.
|
|
|
|
if (-e "$tmpDir/unpacked/top-level") {
|
|
|
|
open TOPLEVEL, "<$tmpDir/unpacked/top-level" or die;
|
|
|
|
while (<TOPLEVEL>) { print "$_"; }
|
|
|
|
close TOPLEVEL;
|
|
|
|
}
|