1{
2 lib,
3 runCommand,
4 writeText,
5}:
6
7{
8 beforeDir,
9 afterDir,
10 evalSystem,
11}:
12
13let
14 /*
15 Computes the key difference between two attrs
16
17 {
18 added: [ <keys only in the second object> ],
19 removed: [ <keys only in the first object> ],
20 changed: [ <keys with different values between the two objects> ],
21 }
22 */
23 diff =
24 let
25 filterKeys = cond: attrs: lib.attrNames (lib.filterAttrs cond attrs);
26 in
27 old: new: {
28 added = filterKeys (n: _: !(old ? ${n})) new;
29 removed = filterKeys (n: _: !(new ? ${n})) old;
30 changed = filterKeys (
31 n: v:
32 # Filter out attributes that don't exist anymore
33 (new ? ${n})
34
35 # Filter out attributes that are the same as the new value
36 && (v != (new.${n}))
37 ) old;
38 };
39
40 getAttrs =
41 dir:
42 let
43 raw = builtins.readFile "${dir}/${evalSystem}/paths.json";
44 # The file contains Nix paths; we need to ignore them for evaluation purposes,
45 # else there will be a "is not allowed to refer to a store path" error.
46 data = builtins.unsafeDiscardStringContext raw;
47 in
48 builtins.fromJSON data;
49
50 beforeAttrs = getAttrs beforeDir;
51 afterAttrs = getAttrs afterDir;
52 diffAttrs = diff beforeAttrs afterAttrs;
53 diffJson = writeText "diff.json" (builtins.toJSON diffAttrs);
54in
55runCommand "diff" { } ''
56 mkdir -p $out/${evalSystem}
57
58 cp -r ${beforeDir} $out/before
59 cp -r ${afterDir} $out/after
60 cp ${diffJson} $out/${evalSystem}/diff.json
61''