summaryrefslogtreecommitdiff
path: root/utils/default.nix
blob: d00357af66182692c074d725a1a5874e44503e3a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
{ lib }:
rec {
  inherit (builtins) readDir;
  inherit (lib) filterAttrs hasSuffix removeSuffix mapAttrs' nameValuePair isFunction functionArgs setFunctionArgs id;
  mapFilterAttrs = seive: f: attrs: filterAttrs seive (mapAttrs' f attrs);
  recImport = { dir, _import ? name: _base: import "${toString dir}/${name}" }:
    mapFilterAttrs
      (_: v: v != null)
      (n: v:
        if n != "default.nix" && hasSuffix ".nix" n && v == "regular"
        then
          let name = removeSuffix ".nix" n; in nameValuePair (name) (_import n name)
        else
          if v == "directory"
          then
            nameValuePair n (_import n n)
          else
            nameValuePair ("") (null))
      (readDir dir);

  types.attrNameSet = attr:
    let
      elemType = lib.types.enum (builtins.attrNames attr);
    in lib.types.mkOptionType rec {
      name = "attrNameSet";
      description = "set of names taken from an attribute set";
      check = lib.isList;
      emptyValue = { value = {}; };
      getSubOptions = prefix: elemType.getSubOptions (prefix ++ ["*"]);
      getSubModules = elemType.getSubModules;
      substSubModules = m: lib.types.listOf (elemType.substSubModules m);
      functor = (lib.types.defaultFunctor name) // { wrapped = elemType; };
      merge = loc: defs: map (x: x.value) (lib.lists.filter (x: x ? value) (lib.lists.unique (lib.lists.concatLists (lib.lists.imap1 (n: def:
        lib.lists.imap1 (m: def':
          (lib.modules.mergeDefinitions
            (loc ++ ["[definition ${toString n}-entry ${toString m}]"])
            elemType
            [{ inherit (def) file; value = def'; }]
          ).optionalValue
        ) def.value
      ) defs))));
    };

  overrideModuleArgs =
    let
      overrideModuleArgs = module: appOverride: if isFunction module then overrideModuleArgs' module appOverride else module;
      overrideModuleArgs' = module: appOverride: setFunctionArgs (inputs: overrideModuleArgs (module (appOverride inputs)) id) (functionArgs module);
    in overrideModuleArgs;
  
  overrideModuleOutput =
    let
      overrideModuleOutput = module: appOverride: if isFunction module then overrideModuleOutput' module appOverride else appOverride module;
      overrideModuleOutput' = module: appOverride: setFunctionArgs (inputs: overrideModuleOutput (module inputs) appOverride) (functionArgs module);
    in overrideModuleOutput;

  overrideModule = module: appInput: appOutput: overrideModuleOutput (overrideModuleArgs module appInput) appOutput;
}