2006-01-12 16:17:51 +01:00
|
|
|
#! @perl@ -w
|
|
|
|
|
|
|
|
# This tool computes the closure of a path (using "nix-store --query
|
|
|
|
# --requisites") and puts the contents of each path in the closure in
|
|
|
|
# a big NAR archive that can be installed on another Nix installation
|
|
|
|
# using "nix-unpack-closure".
|
|
|
|
|
|
|
|
# TODO: make this program "streamy", i.e., don't use a temporary
|
|
|
|
# directory.
|
|
|
|
|
|
|
|
use strict;
|
2006-10-04 20:58:11 +02:00
|
|
|
use File::Temp qw(tempdir);
|
2006-01-12 16:17:51 +01:00
|
|
|
|
|
|
|
my $binDir = $ENV{"NIX_BIN_DIR"};
|
|
|
|
$binDir = "@bindir@" unless defined $binDir;
|
|
|
|
|
2006-10-04 20:58:11 +02:00
|
|
|
my $tmpDir = tempdir("nix-pack-closure.XXXXXX", CLEANUP => 1, TMPDIR => 1)
|
|
|
|
or die "cannot create a temporary directory";
|
|
|
|
|
2007-08-10 02:28:44 +02:00
|
|
|
mkdir "$tmpDir/contents", 0755 or die;
|
|
|
|
mkdir "$tmpDir/references", 0755 or die;
|
|
|
|
mkdir "$tmpDir/derivers", 0755 or die;
|
2006-01-12 16:17:51 +01:00
|
|
|
|
2007-01-13 20:50:42 +01:00
|
|
|
open TOPLEVEL, ">$tmpDir/top-level" or die;
|
2006-01-12 16:17:51 +01:00
|
|
|
|
|
|
|
|
|
|
|
my %storePaths;
|
|
|
|
|
|
|
|
|
|
|
|
while (@ARGV) {
|
|
|
|
my $storePath = shift @ARGV;
|
|
|
|
|
2007-01-13 20:50:42 +01:00
|
|
|
# $storePath might be a symlink to the store, so resolve it.
|
|
|
|
$storePath = (`$binDir/nix-store --query --resolve '$storePath'`
|
|
|
|
or die "cannot resolve `$storePath'");
|
|
|
|
chomp $storePath;
|
|
|
|
print TOPLEVEL $storePath, "\n";
|
|
|
|
|
2006-01-12 16:17:51 +01:00
|
|
|
# Get the closure of this path.
|
|
|
|
my $pid = open(READ,
|
2006-01-27 00:18:46 +01:00
|
|
|
"$binDir/nix-store --query --requisites '$storePath'|") or die;
|
2006-01-12 16:17:51 +01:00
|
|
|
|
|
|
|
while (<READ>) {
|
|
|
|
chomp;
|
|
|
|
die "bad: $_" unless /^\//;
|
|
|
|
$storePaths{$_} = "";
|
|
|
|
}
|
|
|
|
|
|
|
|
close READ or die "nix-store failed: $?";
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-02-20 23:49:08 +01:00
|
|
|
close TOPLEVEL or die;
|
|
|
|
|
|
|
|
|
2006-01-12 16:17:51 +01:00
|
|
|
foreach my $storePath (sort(keys %storePaths)) {
|
|
|
|
print STDERR "packing `$storePath'...\n";
|
|
|
|
|
|
|
|
$storePath =~ /\/([^\/]+)$/;
|
|
|
|
my $name = $1;
|
|
|
|
|
|
|
|
system("$binDir/nix-store --dump '$storePath' > $tmpDir/contents/$name") == 0
|
|
|
|
or die "nix-store --dump failed on `$storePath': $?";
|
|
|
|
|
|
|
|
system("$binDir/nix-store --query --references '$storePath' > $tmpDir/references/$name") == 0
|
|
|
|
or die "nix-store --query --references failed on `$storePath': $?";
|
|
|
|
|
|
|
|
system("$binDir/nix-store --query --deriver '$storePath' > $tmpDir/derivers/$name") == 0
|
|
|
|
or die "nix-store --query --deriver failed on `$storePath': $?";
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
# Write a NAR archive of everything to standard output.
|
|
|
|
system("nix-store --dump '$tmpDir'") == 0
|
|
|
|
or die "nix-store --dump failed";
|