{ pkgs, ... }: let inherit (builtins) genericClosure hasAttr head length map match tail ; inherit (pkgs) runCommandLocal writeText; inherit (pkgs.lib) concatLines concatLists concatMap concatStringsSep filter isDerivation isList mapAttrsToList ; in rec { # Map a drv or list of drvs to a list of output drvs drvOutputs = drv: if isList drv then concatMap drvOutputs drv else if hasAttr "outputs" drv then map (out: drv.${out}) drv.outputs else [ drv ]; # Map a drv or list of drvs to the outputs of referenced derivations drvDeps = drv: if isList drv then concatMap drvDeps drv else mapAttrsToList ( k: v: if isDerivation v then (drvOutputs v) else if isList v then concatMap drvOutputs (filter isDerivation v) else [ ] ) drv; # Get the reference closure of a derivation or list of derivations # This may miss dependencies that are only in-closure from string context drvClosure = let wrap = drv: { key = drv.outPath; inherit drv; }; in drv: map (obj: obj.drv) (genericClosure { startSet = map wrap (drvOutputs drv); operator = obj: map wrap (concatLists (drvDeps obj.drv.drvAttrs)); }); maintainable = drv: hasAttr "meta" drv && hasAttr "maintainers" drv.meta; drvMaintainers = drv: if maintainable drv then drv.meta.maintainers else [ ]; # Construct a link to a derivation's source in github:NixOS/nixpkgs drvSource = drv: let parts = match "/nix/store/[^/]+/(.*):([0-9]*)" drv.meta.position; in if hasAttr "meta" drv && hasAttr "position" drv.meta then "https://github.com/NixOS/nixpkgs/blob/master/${head parts}#L${head (tail parts)}" else ""; mainInfo = drv: { name = drv.name; maintainers = map (main: toString main.github) (drvMaintainers drv); source = drvSource drv; }; stringJoin = objToString: objs: writeText "txt" (concatLines (map objToString objs)); closureInfo = drv: map mainInfo (filter maintainable (drvClosure drv)); allMaintainers = drv: let info = closureInfo drv; infoToString = info: "${info.name} ${concatStringsSep "," info.maintainers}"; in runCommandLocal "all-maintainers.txt" { } '' <${stringJoin infoToString info} sort -u | ${pkgs.unixtools.column}/bin/column -t > $out ''; noMaintainers = drv: let info = closureInfo drv; unmaintained = filter (info: (length info.maintainers) == 0) info; infoToString = info: "${info.name} ${info.source}"; in runCommandLocal "unmaintained.txt" { } '' <${stringJoin infoToString unmaintained} sort -u | ${pkgs.unixtools.column}/bin/column -t > $out ''; expandInput = input: if (input.class or null == "nixos") && (input._type or null == "configuration") then [ input.config.system.build.toplevel input.config.environment.systemPackages ] else input; }