diff options
author | Benedikt Peetz <benedikt.peetz@b-peetz.de> | 2024-10-24 14:59:29 +0200 |
---|---|---|
committer | Benedikt Peetz <benedikt.peetz@b-peetz.de> | 2024-10-24 14:59:29 +0200 |
commit | 0cc353f49f9c5d0e0bd203a6854b488a58daaa96 (patch) | |
tree | 48d4a821a842f94e3614f7c310423d9d2c98cc21 /lib/by-name-overlay.nix | |
parent | refactor(modules/unison): Migrate to `by-name` and parameterize (diff) | |
download | nixos-config-0cc353f49f9c5d0e0bd203a6854b488a58daaa96.tar.gz nixos-config-0cc353f49f9c5d0e0bd203a6854b488a58daaa96.zip |
refactor({modules,pkgs}/by-name-overlay): De-duplicate in a `nixLib`
Diffstat (limited to 'lib/by-name-overlay.nix')
-rw-r--r-- | lib/by-name-overlay.nix | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/lib/by-name-overlay.nix b/lib/by-name-overlay.nix new file mode 100644 index 00000000..cc8bcb67 --- /dev/null +++ b/lib/by-name-overlay.nix @@ -0,0 +1,65 @@ +{warn}: +# Adapted from this: https://github.com/NixOS/nixpkgs/blob/1814b56453c91192f6d5a6276079948f9fe96c18/pkgs/top-level/by-name-overlay.nix +# This file should not depend on `pkgs` and thus not use `lib`. +{ + baseDirectory, + fileName, + finalizeFunction, +}: let + # Takes a list of attrs as input and returns one merged attr set. + flattenAttrs = list: + if builtins.isList list + then + builtins.foldl' (acc: elem: + if builtins.isList elem + # Merging them with `//` is okay here, as we can be sure that the attr names are + # unique (they were separate dictionary after all) + then acc // (flattenAttrs elem) + else acc // elem) {} + list + else list; + + # From nixpkgs/lib {{{ + # These functions are taken straight out of the `nixpkgs/lib`. + # We can't depended on `pkgs` (and thus on `lib`), because the `pkgs` module argument + # is only defined in the `nixpkgs` module (which is imported through this function). + mapAttrsToList = f: attrs: + builtins.map (name: f name attrs.${name}) (builtins.attrNames attrs); + + nameValuePair = name: value: {inherit name value;}; + filterAttrs = pred: set: + builtins.listToAttrs (builtins.concatMap (name: let + v = set.${name}; + in + if pred name v + then [(nameValuePair name v)] + else []) (builtins.attrNames set)); + # }}} + + # Module files for a single shard + # Type: String -> String -> ListOf Path + namesForShard = shard: type: + if type != "directory" + then warn "Ignored non-directory, whilst importing by-name directory (${fileName}): '${shard}'" {} + else let + mkPath = name: _type: let + path = baseDirectory + "/${shard}/${name}" + "/${fileName}"; + in + if builtins.pathExists path + then path + else warn "'${builtins.toString path}' does not exist. Skipped" null; + in + filterAttrs (name: value: value != null) + (builtins.mapAttrs + mkPath + (builtins.readDir (baseDirectory + "/${shard}"))); + + # A list of all module paths. + # These can the be simply injected into `import` + files = flattenAttrs (mapAttrsToList namesForShard (builtins.readDir baseDirectory)); + output = + builtins.mapAttrs + finalizeFunction + files; +in + output |