Support bundling nixos configurations

This commit is contained in:
Tim Van Baak 2024-07-28 20:09:17 -07:00
parent aae8892a4a
commit 079d222614
2 changed files with 73 additions and 44 deletions

View File

@ -3,8 +3,11 @@ let
inherit (builtins)
genericClosure
hasAttr
head
length
map
match
tail
;
inherit (pkgs) runCommandLocal writeText;
inherit (pkgs.lib)
@ -19,9 +22,20 @@ let
;
in
rec {
drvOutputs = drv: if hasAttr "outputs" drv then map (out: drv.${out}) drv.outputs else [ drv ];
# 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
@ -31,6 +45,9 @@ rec {
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: {
@ -43,50 +60,58 @@ rec {
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 [ ];
nobodyMaintains =
drv: hasAttr "meta" drv && hasAttr "maintainers" drv.meta && (length drv.meta.maintainers) == 0;
# 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
closure = drvClosure drv;
maintainers = concatMap drvMaintainers closure;
mainToString = m: "${m.name} (${m.email})";
info = closureInfo drv;
infoToString = info: "${info.name} ${concatStringsSep "," info.maintainers}";
in
runCommandLocal "uniq-maintainers.txt" { } ''
<${stringJoin mainToString maintainers} sort | uniq -c > $out
runCommandLocal "all-maintainers.txt" { } ''
<${stringJoin infoToString info} sort -u | ${pkgs.unixtools.column}/bin/column -t > $out
'';
noMaintainers =
drv:
let
closure = drvClosure drv;
unmaintained = filter nobodyMaintains closure;
drvToString = drv: "${drv.name} ${drv.meta.position}";
info = closureInfo drv;
unmaintained = filter (info: (length info.maintainers) == 0) info;
infoToString = info: "${info.name} ${info.source}";
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
runCommandLocal "unmaintained.txt" { } ''
<${stringJoin infoToString unmaintained} sort -u | ${pkgs.unixtools.column}/bin/column -t > $out
'';
listMaintainers =
drv:
let
closure = drvClosure drv;
maintainableDrvs = filter maintainable closure;
maintainersToString =
maintainers: concatStringsSep "," (map (main: toString main.github) maintainers);
drvToString = drv: "${drv.name} ${maintainersToString (drvMaintainers drv)}";
in
runCommandLocal "maintainers.txt" { } ''
<${stringJoin drvToString maintainableDrvs} 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;
}

View File

@ -5,13 +5,17 @@
system = "x86_64-linux";
pkgs = nixpkgs.legacyPackages.${system};
lib = import ./default.nix { inherit pkgs; };
inherit (lib)
allMaintainers
expandInput
noMaintainers
;
in
{
bundlers."x86_64-linux" = rec {
default = adopt;
maintainers = lib.allMaintainers;
adopt = lib.noMaintainers;
list = lib.listMaintainers;
default = unmaintained;
all = drv: allMaintainers (expandInput drv);
unmaintained = drv: noMaintainers (expandInput drv);
};
formatter."x86_64-linux" = pkgs.nixfmt-rfc-style;