92 lines
3.7 KiB
Nix
92 lines
3.7 KiB
Nix
|
let
|
||
|
flake = builtins.getFlake "/home/lyn/flake";
|
||
|
pkgs = import flake.inputs.nixpkgs {};
|
||
|
lib = pkgs.lib;
|
||
|
|
||
|
mapAttrKVs = mapFn: attrs: builtins.foldl' (acc: cur: acc // {${cur.key} = cur.value;}) {} (builtins.attrValues (builtins.mapAttrs mapFn attrs));
|
||
|
#kv = key: value: {inherit key value;};
|
||
|
recurseNaive = curPath: fn: mapAttrKVs (k: v: let
|
||
|
match = builtins.match "(.*)[.]nix" k;
|
||
|
in if v == "regular" && match != null then {key = builtins.elemAt match 0; value = fn (curPath + ("/" + k));}
|
||
|
else if v == "directory" then {key = k; value = recurseNaive (curPath + ("/" + k)) fn;}
|
||
|
else {key = null; value = null;}
|
||
|
) (builtins.readDir curPath);
|
||
|
|
||
|
getAttrKVsRec = prefix: as: pkgs.lib.flatten (pkgs.lib.mapAttrsToList (k: v:
|
||
|
if pkgs.lib.isAttrs v then getAttrKVsRec (prefix ++ [k]) v
|
||
|
else [{path = prefix ++ [k]; value = v;}]
|
||
|
) as);
|
||
|
|
||
|
getPathKVsRec = prefix: dir: getAttrKVsRec prefix (lib.packagesFromDirectoryRecursive { callPackage = path: x: path; directory = dir; });
|
||
|
|
||
|
unifyMod = (import ./modules-extracted.nix {lib = lib;}).unifyModuleSyntax;
|
||
|
transformLocalMod = {path, value}: p: let
|
||
|
param = p // {
|
||
|
cfg = lib.getAttrFromPath path p.config;
|
||
|
};
|
||
|
|
||
|
pathStr = builtins.concatStringsSep "." path;
|
||
|
modFn = p: let i = import value; in if lib.isFunction i then i p else i;
|
||
|
modUni = unifyMod pathStr pathStr (builtins.removeAttrs modRaw ["opt" "mod"]);
|
||
|
|
||
|
meta = modRaw.mod or {};
|
||
|
fileCtx = str: "${modUni._file} (mkLocalMods ${str})";
|
||
|
enablePath = path ++ ["enable"];
|
||
|
|
||
|
merge = cur: upd:
|
||
|
|
||
|
runExts = exts: let
|
||
|
nul = x: rec {
|
||
|
# First pass
|
||
|
args = p; # Args to call the module with. This immediately changes the params of `raw`, `mod` etc. through Nix magic
|
||
|
deletedKeys = ["opt" "mod"]; # Keys to delete before calling unifyModuleSyntax
|
||
|
|
||
|
# Second pass
|
||
|
imports = {}; # Put any modules to import as *attributes* here (for other extensions to modify them)
|
||
|
raw = modFn x.args; # The raw module result, called with `args`
|
||
|
mod = unifyMod pathStr pathStr (builtins.removeAttrs raw x.deletedKeys); # The unified module, e.g. the result of `unifyModuleSyntax .. .. raw`, and has the default module attrs
|
||
|
meta = raw.mod or {}; # Equivalent to raw.mod, contains metadata of the module
|
||
|
};
|
||
|
firstPass = builtins.foldl' (acc: ext:
|
||
|
builtins.foldl' (acc: ext: let
|
||
|
acc' = acc // (let acc2 = (ext acc) // acc; in rec {
|
||
|
raw = modFn acc2.args;
|
||
|
mod = unifyMod pathStr pathStr (builtins.removeAttrs raw acc2.deletedKeys);
|
||
|
meta = raw.mod or {};
|
||
|
});
|
||
|
res = lib.recursiveUpdate acc' (ext acc');
|
||
|
in res) exts
|
||
|
|
||
|
addMod = c: ctx: newMod: { mod.imports = c.mod.imports ++ [ (newMod // {_file = fileCtx ctx;}) ]; };
|
||
|
|
||
|
defaultExtensions = [
|
||
|
(c: { imports.opt = {
|
||
|
name = "`opt` processor";
|
||
|
options = lib.setAttrByPath c.path raw.opt;
|
||
|
};})
|
||
|
(c: { imports.enable = {
|
||
|
name "`enable` definition";
|
||
|
opt.enable = lib.mkEnableOption (c.meta.desc or c.meta.description or c.meta.name or pathStr);
|
||
|
};})
|
||
|
(c: {
|
||
|
|
||
|
})
|
||
|
]
|
||
|
|
||
|
imports = [ {
|
||
|
_file = fileCtx "`opt` processor";
|
||
|
options = lib.setAttrByPath path modRaw.opt;
|
||
|
} {
|
||
|
_file = fileCtx "`enable` definition";
|
||
|
options = lib.setAttrByPath enablePath (lib.mkEnableOption (mod.desc or mod.description or mod.name or pathStr));
|
||
|
} ({config, ...}: {
|
||
|
_file = fileCtx "config wrapper";
|
||
|
config = lib.mkIf (lib.getAttrFromPath enablePath config) modUni.config;
|
||
|
}) ];
|
||
|
|
||
|
newMod = modUni // { imports = modUni.imports ++ imports; config = {}; };
|
||
|
in newMod;
|
||
|
|
||
|
mkLocalMods = {prefix ? [], dir}: { _file = "mkLocalMods collector"; imports = builtins.map transformLocalMod (getPathKVsRec prefix dir); };
|
||
|
in cfg: (pkgs.lib.evalModules { modules = [ (mkLocalMods {prefix = ["lyn"]; dir = ./modules;}) cfg ]; })
|