Skip to content

Instantly share code, notes, and snippets.

@rrbutani
Last active May 16, 2023 06:39
Show Gist options
  • Save rrbutani/32fcfde04ed5275ab88036eb8f4189e5 to your computer and use it in GitHub Desktop.
Save rrbutani/32fcfde04ed5275ab88036eb8f4189e5 to your computer and use it in GitHub Desktop.
{ lib }: {
# Given an attrset of derivations of interest, returns an attrset where each
# corresponding key is the full list of deps for the derivation.
#
# Note: this is far from perfect; this function only walks the usual
# `mkDerivation` dependency list attributes so it'll miss dependencies in
# strings.
collectDeps = pkgSet: let
# dbg = x: builtins.trace (builtins.typeOf x) (builtins.trace x x);
d = path: builtins.unsafeDiscardStringContext path;
# debugLog = builtins.trace;
debugLog = a: b: b;
collectNextDepsForDrv = drv: let
deps = n: let
list =
if isDerivation drv then
if drv ? ${n} then let dep = drv.${n}; in
if isList dep then dep
else if isDerivation dep then [ dep ]
else []
else []
else []
;
in listToAttrs (map
(dep: {
name = if (builtins.typeOf dep) == "path"
then d dep
else d dep.outPath
;
value = dep;
})
(filter (x: x != null)
(debugLog "${drv.pname or drv.name or drv}.${n}" list)
)
);
in {}
// (deps "depsBuildBuild") // (deps "depsBuildBuildPropagated")
// (deps "nativeBuildInputs") // (deps "propagatedNativeBuildInputs")
// (deps "depsBuildTarget") // (deps "depsBuildTargetPropagated")
// (deps "depsHostHost") // (deps "depsHostHostPropagated")
// (deps "buildInputs") // (deps "propagatedBuildInputs")
// (deps "depsTargetTarget") // (deps "depsTargetTargetPropagated")
# // (deps "src") # TODO: why does this recurse infinitely?
;
# Note that we're keeping the whole derivation around here. For some use
# cases it may be a performance win to "inline" this and to only keep around
# the attributes of interest from the deps.
nextDeps = builtins.genericClosure {
startSet = mapAttrsToList (n: v: {
key = v.outPath; val = v; next = collectNextDepsForDrv v;
}) pkgSet;
operator = { next, ... }: mapAttrsToList (outPath: drv: {
key = outPath;
val = drv;
next = collectNextDepsForDrv drv;
}) next;
};
# `outPath` -> attrSet(outPath -> drv); memoized
fullDepMap = listToAttrs (map ({ key, val, next }: let
outPath = key;
drv = val;
depSet = foldl mergeAttrs next (map (dep: fullDepMap.${dep}) (attrNames next));
in {
name = d outPath;
value = depSet;
}
) nextDeps);
in mapAttrs (_: v: attrValues (fullDepMap.${d v.outPath})) pkgSet;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment