mirror of
https://github.com/NixOS/nixpkgs.git
synced 2025-11-10 09:43:30 +01:00
The change to use `builtins.storePath` was good - for when the store
path *is* already part of the nix store. In all my tests so far, that
was already the case, because I was iterating on the solution and the
Eval results stayed the same.
But when this is run on a entirely new commit, these the values for
`afterDir` and `combinedDir` are *not* in the store, yet. As part of
running `eval.full` on a new commit they will be created. `eval.full` is
linked up, so that the values passed around there will actually be
derivations, which might not be realized, yet.
Checking whether the input is a path or not fixes this for both cases.
(cherry picked from commit b9d4098221)
87 lines
2.5 KiB
Nix
87 lines
2.5 KiB
Nix
{
|
|
lib,
|
|
runCommand,
|
|
writeText,
|
|
}:
|
|
|
|
{
|
|
beforeDir,
|
|
afterDir,
|
|
evalSystem,
|
|
}:
|
|
|
|
let
|
|
# Usually we expect a derivation, but when evaluating in multiple separate steps, we pass
|
|
# nix store paths around. These need to be turned into (fake) derivations again to track
|
|
# dependencies properly.
|
|
# We use two steps for evaluation, because we compare results from two different checkouts.
|
|
# CI additionalls spreads evaluation across multiple workers.
|
|
before = if lib.isDerivation beforeDir then beforeDir else lib.toDerivation beforeDir;
|
|
after = if lib.isDerivation afterDir then afterDir else lib.toDerivation afterDir;
|
|
|
|
/*
|
|
Computes the key difference between two attrs
|
|
|
|
{
|
|
added: [ <keys only in the second object> ],
|
|
removed: [ <keys only in the first object> ],
|
|
changed: [ <keys with different values between the two objects> ],
|
|
rebuilds: [ <keys in the second object with values not present at all in first object> ],
|
|
}
|
|
*/
|
|
diff =
|
|
old: new:
|
|
let
|
|
filterKeys = cond: attrs: lib.attrNames (lib.filterAttrs cond attrs);
|
|
oldOutputs = lib.pipe old [
|
|
(lib.mapAttrsToList (_: lib.attrValues))
|
|
lib.concatLists
|
|
(lib.flip lib.genAttrs (_: true))
|
|
];
|
|
in
|
|
{
|
|
added = filterKeys (n: _: !(old ? ${n})) new;
|
|
removed = filterKeys (n: _: !(new ? ${n})) old;
|
|
changed = filterKeys (
|
|
n: v:
|
|
# Filter out attributes that don't exist anymore
|
|
(new ? ${n})
|
|
|
|
# Filter out attributes that are the same as the new value
|
|
&& (v != (new.${n}))
|
|
) old;
|
|
# A "rebuild" is every attrpath ...
|
|
rebuilds = filterKeys (
|
|
_: pkg:
|
|
# ... that has at least one output ...
|
|
lib.any (
|
|
output:
|
|
# ... which has not been built in "old" already.
|
|
!(oldOutputs ? ${output})
|
|
) (lib.attrValues pkg)
|
|
) new;
|
|
};
|
|
|
|
getAttrs =
|
|
dir:
|
|
let
|
|
raw = builtins.readFile "${dir}/${evalSystem}/paths.json";
|
|
# The file contains Nix paths; we need to ignore them for evaluation purposes,
|
|
# else there will be a "is not allowed to refer to a store path" error.
|
|
data = builtins.unsafeDiscardStringContext raw;
|
|
in
|
|
builtins.fromJSON data;
|
|
|
|
beforeAttrs = getAttrs before;
|
|
afterAttrs = getAttrs after;
|
|
diffAttrs = diff beforeAttrs afterAttrs;
|
|
diffJson = writeText "diff.json" (builtins.toJSON diffAttrs);
|
|
in
|
|
runCommand "diff" { } ''
|
|
mkdir -p $out/${evalSystem}
|
|
|
|
cp -r ${before} $out/before
|
|
cp -r ${after} $out/after
|
|
cp ${diffJson} $out/${evalSystem}/diff.json
|
|
''
|