about summary refs log tree commit diff
path: root/scripts/nix-pack-closure.in
blob: 0634537d0a571d9a83d92a6b4a56b2ece4ec25df (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
#! @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;
use File::Temp qw(tempdir);

my $binDir = $ENV{"NIX_BIN_DIR"};
$binDir = "@bindir@" unless defined $binDir;

my $tmpDir = tempdir("nix-pack-closure.XXXXXX", CLEANUP => 1, TMPDIR => 1)
    or die "cannot create a temporary directory";

mkdir "$tmpDir/contents", 0755 or die;
mkdir "$tmpDir/references", 0755 or die;
mkdir "$tmpDir/derivers", 0755 or die;

open TOPLEVEL, ">$tmpDir/top-level" or die;


my %storePaths;


while (@ARGV) {
    my $storePath = shift @ARGV;

    # $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";

    # Get the closure of this path.
    my $pid = open(READ,
        "$binDir/nix-store --query --requisites '$storePath'|") or die;
    
    while (<READ>) {
        chomp;
        die "bad: $_" unless /^\//;
        $storePaths{$_} = "";
    }

    close READ or die "nix-store failed: $?";
}


close TOPLEVEL or die;


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";