The part about finding `_hydraAggregate`/`constituents` is basically
derived from `hydra-eval-jobs`, however the part about
`namedConstituents` has been changed: we still stream out jobs when they
appear, however we suppress this for aggregate jobs.
These jobs are post-processed at the end, i.e. if `namedConstituents`
exist, these will be mapped to the drvPath of the other jobs. Then, the
drv will be rewritten to contain the drvPath of said jobs[1] and the
JSON containing the rewritten `drvPath` will be printed out.
[1] This was an optimization to reduce the memory footprint of
evaluating e.g. the `tested` job in nixpkgs.
This ensures correct handling of attrnames with a dot in them and will
not throw errors about illegal attrnames.
Additionally this escapes any attributes containing dots in the JSON
output and adds another field called `attrPath` which contains the
attribute path as a list.
Example output:
```
{
"attr": "hello",
"attrPath": [
"hello"
],
"drvPath": "/nix/store/n204jib73z55cp9s0rmw1c5v5q528j7v-hello-2.12.drv",
"name": "hello-2.12",
"outputs": {
"out": "/nix/store/h59dfk7dwrn7d2csykh9z9xm2miqmrnz-hello-2.12"
},
"system": "x86_64-linux"
}
```
This will respect `recurseForDerivations` when iterating over attrsets.
Example expression:
``` nix
{ system ? builtins.currentSystem }:
{
recurseForDerivations = true;
# This should build as it's in the top-level attrset
drvA = derivation {
inherit system;
name = "drvA";
builder = ":";
};
dontRecurse = {
# This shouldn't build as `recurseForDerivations = true;` is not set
# recurseForDerivations = true;
# This should not build
drvB = derivation {
inherit system;
name = "drvA";
builder = ":";
};
};
recurse = {
# This should build
recurseForDerivations = true;
# This should not build
drvC = derivation {
inherit system;
name = "drvC";
builder = ":";
};
};
}
```