about summary refs log tree commit diff
path: root/scripts/copying-collector.pl
blob: 2e8be2d41f32462363f748bbbf1938d8e3171261 (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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
#! /usr/bin/perl -w

use strict;

my @paths = `nix-store -qR /home/eelco/.nix-profile/bin/firefox`;

my %copyMap;
my %rewriteMap;


my $counter = 0;

foreach my $path (@paths) {
    chomp $path;

    $path =~ /^(.*)\/([^-]+)-(.*)$/ or die "invalid store path `$path'";
    my $hash = $2;

#    my $newHash = "deadbeef" . (sprintf "%024d", $counter++);
    my $newHash = "deadbeef" . substr($hash, 0, 24);
    my $newPath = "/home/eelco/chroot/$1/$newHash-$3";

    die unless length $newHash == length $hash;

    $copyMap{$path} = $newPath;
    $rewriteMap{$hash} = $newHash;
}


my %rewriteMap2;


sub rewrite;
sub rewrite {
    my $src = shift;
    my $dst = shift;

    if (-l $dst) {

        my $target = readlink $dst or die;

        foreach my $srcHash (keys %rewriteMap2) {
            my $dstHash = $rewriteMap{$srcHash};
            print "  $srcHash -> $dstHash\n";
            $target =~ s/$srcHash/$dstHash/g;
        }

        unlink $dst or die;

        symlink $target, $dst;
        
    }

    elsif (-f $dst) {

        print "$dst\n";

        foreach my $srcHash (keys %rewriteMap2) {
            my $dstHash = $rewriteMap{$srcHash};
            print "  $srcHash -> $dstHash\n";

            my @stats = lstat $dst or die;
            
            system "sed s/$srcHash/$dstHash/g < '$dst' > '$dst.tmp'";
            die if $? != 0;
            rename "$dst.tmp", $dst or die;

            chmod $stats[2], $dst or die;
        }

    }

    elsif (-d $dst) {

        chmod 0755, $dst;
        
        opendir(DIR, "$dst") or die "cannot open `$dst': $!";
        my @files = readdir DIR;
        closedir DIR;
        
        foreach my $file (@files) {
            next if $file eq "." || $file eq "..";
            rewrite "$src/$file", "$dst/$file";
        }
    }
}


foreach my $src (keys %copyMap) {
    my $dst = $copyMap{$src};
    print "$src -> $dst\n";

    if (!-e $dst) {
        system "cp -prd $src $dst";
        die if $? != 0;

        my @refs = `nix-store -q --references $src`;

        %rewriteMap2 = ();
        foreach my $ref (@refs) {
            chomp $ref;

            $ref =~ /^(.*)\/([^-]+)-(.*)$/ or die "invalid store path `$ref'";
            my $hash = $2;

            $rewriteMap2{$hash} = $rewriteMap{$hash};
        }

        rewrite $src, $dst;
    }
}