outputAttrs: let attrNamePathToString = attrNamePath: builtins.concatStringsSep "." attrNamePath; outputInfo = drv: builtins.listToAttrs (builtins.map (outputName: { name = outputName; value = { store_path = drv."${outputName}".outPath; }; }) drv.outputs); recurseAttrs = attrs: attrNamePath: builtins.concatLists (builtins.attrValues ( builtins.mapAttrs (attrName: attrValue: if builtins.typeOf attrValue == "set" then if builtins.hasAttr "type" attrValue then if attrValue.type == "derivation" then [ { name = attrNamePathToString (attrNamePath ++ [ attrName ]); value = { name = attrValue.name; derivation_path = attrValue.drvPath; system = attrValue.system; outputs = outputInfo attrValue; }; } ] else [ "unknown type" ] else recurseAttrs attrValue (attrNamePath ++ [ attrName ]) else [] ) attrs )); in builtins.listToAttrs (recurseAttrs outputAttrs [])