{ pkgs, ... }: let inherit (builtins) genericClosure hasAttr length map ; inherit (pkgs) runCommandLocal writeText; inherit (pkgs.lib) concatLines concatLists concatMap filter isDerivation isList mapAttrsToList ; in rec { drvOutputs = drv: if hasAttr "outputs" drv then map (out: drv.${out}) drv.outputs else [ drv ]; drvDeps = drv: mapAttrsToList ( k: v: if isDerivation v then (drvOutputs v) else if isList v then concatMap drvOutputs (filter isDerivation v) else [ ] ) drv; 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)); }); drvMaintainers = drv: if !hasAttr "meta" drv then [ ] else if !hasAttr "maintainers" drv.meta then [ ] else drv.meta.maintainers; nobodyMaintains = drv: hasAttr "meta" drv && hasAttr "maintainers" drv.meta && (length drv.meta.maintainers) == 0; stringJoin = objToString: objs: writeText "txt" (concatLines (map objToString objs)); allMaintainers = drv: let closure = drvClosure drv; maintainers = concatMap drvMaintainers closure; mainToString = m: "${m.name} (${m.email})"; in runCommandLocal "uniq-maintainers.txt" { } '' <${stringJoin mainToString maintainers} sort | uniq -c > $out ''; noMaintainers = drv: let closure = drvClosure drv; unmaintained = filter nobodyMaintains closure; drvToString = drv: "${drv.name} ${drv.meta.position}"; in runCommandLocal "no-maintainers.txt" { } '' <${stringJoin drvToString unmaintained} sort -u \ | sed 's/\/nix\/store\/[^/]*/https:\/\/github.com\/NixOS\/nixpkgs\/blob\/master/' \ | sed 's/.nix:\(.*\)$/.nix#L\1/' \ | ${pkgs.unixtools.column}/bin/column -t \ > $out ''; }