at master 2.6 kB view raw
1{ 2 lib, 3 runCommand, 4 writeText, 5}: 6 7{ 8 beforeDir, 9 afterDir, 10 evalSystem, 11}: 12 13let 14 # Usually we expect a derivation, but when evaluating in multiple separate steps, we pass 15 # nix store paths around. These need to be turned into (fake) derivations again to track 16 # dependencies properly. 17 # We use two steps for evaluation, because we compare results from two different checkouts. 18 # CI additionalls spreads evaluation across multiple workers. 19 before = if lib.isDerivation beforeDir then beforeDir else lib.toDerivation beforeDir; 20 after = if lib.isDerivation afterDir then afterDir else lib.toDerivation afterDir; 21 22 /* 23 Computes the key difference between two attrs 24 25 { 26 added: [ <keys only in the second object> ], 27 removed: [ <keys only in the first object> ], 28 changed: [ <keys with different values between the two objects> ], 29 rebuilds: [ <keys in the second object with values not present at all in first object> ], 30 } 31 */ 32 diff = 33 old: new: 34 let 35 filterKeys = cond: attrs: lib.attrNames (lib.filterAttrs cond attrs); 36 oldOutputs = lib.pipe old [ 37 (lib.mapAttrsToList (_: lib.attrValues)) 38 lib.concatLists 39 (lib.flip lib.genAttrs (_: true)) 40 ]; 41 in 42 { 43 added = filterKeys (n: _: !(old ? ${n})) new; 44 removed = filterKeys (n: _: !(new ? ${n})) old; 45 changed = filterKeys ( 46 n: v: 47 # Filter out attributes that don't exist anymore 48 (new ? ${n}) 49 50 # Filter out attributes that are the same as the new value 51 && (v != (new.${n})) 52 ) old; 53 # A "rebuild" is every attrpath ... 54 rebuilds = filterKeys ( 55 _: pkg: 56 # ... that has at least one output ... 57 lib.any ( 58 output: 59 # ... which has not been built in "old" already. 60 !(oldOutputs ? ${output}) 61 ) (lib.attrValues pkg) 62 ) new; 63 }; 64 65 getAttrs = 66 dir: 67 let 68 raw = builtins.readFile "${dir}/${evalSystem}/paths.json"; 69 # The file contains Nix paths; we need to ignore them for evaluation purposes, 70 # else there will be a "is not allowed to refer to a store path" error. 71 data = builtins.unsafeDiscardStringContext raw; 72 in 73 builtins.fromJSON data; 74 75 beforeAttrs = getAttrs before; 76 afterAttrs = getAttrs after; 77 diffAttrs = diff beforeAttrs afterAttrs; 78 diffJson = writeText "diff.json" (builtins.toJSON diffAttrs); 79in 80runCommand "diff" { } '' 81 mkdir -p $out/${evalSystem} 82 83 cp -r ${before} $out/before 84 cp -r ${after} $out/after 85 cp ${diffJson} $out/${evalSystem}/diff.json 86''