2021-12-08 04:20:18 +00:00
|
|
|
{ lib, ... }:
|
2021-12-06 09:55:40 +00:00
|
|
|
|
2021-12-08 04:20:18 +00:00
|
|
|
rec {
|
2021-11-25 11:55:30 +00:00
|
|
|
/* Create an attribute set that represents the structure of the modules
|
|
|
|
inside of a directory. While it can recurse into directories, it will
|
|
|
|
stop once it detects `default.nix` inside.
|
|
|
|
|
2021-11-27 08:04:01 +00:00
|
|
|
Signature:
|
|
|
|
path -> attrset
|
|
|
|
Where:
|
|
|
|
- `path` is the starting point.
|
|
|
|
Returns:
|
|
|
|
An attribute set. The keys are the basename of the file or the directory
|
|
|
|
and the values are the filepath to the Nix file.
|
|
|
|
|
2021-11-25 11:55:30 +00:00
|
|
|
!!! Implementation detail is based from
|
|
|
|
https://github.com/divnix/digga/blob/main/src/importers.nix looking at it
|
|
|
|
multiple times for the purpose of familiarizing myself to coding in Nix
|
|
|
|
and functional programming shtick.
|
|
|
|
|
|
|
|
Example:
|
|
|
|
filesToAttr ./hosts
|
|
|
|
=> { ni = ./hosts/ni/default.nix; zilch = ./hosts/zilch/default.nix }
|
|
|
|
*/
|
|
|
|
filesToAttr = dirPath:
|
|
|
|
let
|
|
|
|
isModule = file: type:
|
2021-11-25 13:45:48 +00:00
|
|
|
(type == "regular" && lib.hasSuffix ".nix" file)
|
|
|
|
|| (type == "directory");
|
2021-11-25 11:55:30 +00:00
|
|
|
|
|
|
|
collect = file: type: {
|
|
|
|
name = lib.removeSuffix ".nix" file;
|
2021-11-25 13:45:48 +00:00
|
|
|
value = let path = dirPath + "/${file}";
|
|
|
|
in if (type == "regular")
|
|
|
|
|| (type == "directory" && lib.pathExists (path + "/default.nix")) then
|
|
|
|
path
|
|
|
|
else
|
|
|
|
filesToAttr path;
|
|
|
|
};
|
2021-11-25 11:55:30 +00:00
|
|
|
|
|
|
|
files = lib.filterAttrs isModule (builtins.readDir dirPath);
|
2021-11-25 13:45:48 +00:00
|
|
|
in lib.filterAttrs (name: value: value != { })
|
|
|
|
(lib.mapAttrs' collect files);
|
2021-11-25 11:55:30 +00:00
|
|
|
|
|
|
|
/* Like `filesToAttr` but does it recursively. Those modules with
|
|
|
|
`default.nix` are ignored and gives the full module directory this time.
|
|
|
|
This is only suitable if you intend to use all of the modules in a given
|
|
|
|
directory.
|
|
|
|
|
2021-11-27 08:04:01 +00:00
|
|
|
Signature:
|
|
|
|
path -> attrset
|
|
|
|
Where:
|
|
|
|
- `path` is the starting point of the scan.
|
|
|
|
Returns:
|
|
|
|
An attribute set. The keys are the basename for each Nix file/directory
|
|
|
|
and the values are the path to the file.
|
|
|
|
|
2021-11-25 11:55:30 +00:00
|
|
|
Examples:
|
2021-11-27 08:04:01 +00:00
|
|
|
filesToAttrRec ./modules
|
|
|
|
=> { agenix = /home/foo-dogsquared/nixos-config/modules/agenix.nix; archiving = /home/foo-dogsquared/nixos-config/modules/archiving.nix; desktop = /home/foo-dogsquared/nixos-config/modules/desktop.nix; dev = /home/foo-dogsquared/nixos-config/modules/dev.nix; editors = /home/foo-dogsquared/nixos-config/modules/editors.nix; themes = { a-happy-gnome = /home/foo-dogsquared/nixos-config/modules/themes/a-happy-gnome; default = /home/foo-dogsquared/nixos-config/modules/themes/default.nix; }; }
|
2021-11-25 11:55:30 +00:00
|
|
|
*/
|
|
|
|
filesToAttrRec = dir:
|
|
|
|
let
|
|
|
|
files = lib.filterAttrs (n: v: n != "default") (filesToAttr dir);
|
|
|
|
|
|
|
|
collect = name: file: {
|
|
|
|
inherit name;
|
2021-11-25 13:45:48 +00:00
|
|
|
|
|
|
|
# Since `filesToAttr` has already filtered the files, we can be assured
|
|
|
|
# it is only either a Nix file or a directory containing a
|
|
|
|
# `default.nix`.
|
|
|
|
value = if (lib.pathIsDirectory file) then filesToAttr file else file;
|
2021-11-25 11:55:30 +00:00
|
|
|
};
|
2021-11-25 13:45:48 +00:00
|
|
|
in lib.listToAttrs (lib.mapAttrsToList collect files);
|
2021-11-25 11:55:30 +00:00
|
|
|
|
2021-11-30 01:03:05 +00:00
|
|
|
/* Collect all modules (results from `filesToAttr`) into a list.
|
|
|
|
|
|
|
|
Signature:
|
|
|
|
attrs -> [ function ]
|
|
|
|
Where:
|
|
|
|
- `attrs` is the set of modules and their path.
|
|
|
|
Returns:
|
|
|
|
- A list of imported modules.
|
|
|
|
|
|
|
|
Example:
|
|
|
|
modulesToList (filesToAttr ../modules)
|
|
|
|
=> [ <lambda> <lambda> <lambda> ]
|
|
|
|
*/
|
|
|
|
modulesToList = attrs:
|
|
|
|
let paths = lib.collect builtins.isPath attrs;
|
|
|
|
in builtins.map (path: import path) paths;
|
|
|
|
|
2021-11-29 09:58:02 +00:00
|
|
|
/* Return an attribute set of valid users from a given list of users.
|
2021-12-06 07:27:51 +00:00
|
|
|
This is a convenience function for getting users from the `./users` directory.
|
2021-11-29 09:58:02 +00:00
|
|
|
|
|
|
|
Signature:
|
|
|
|
list -> attrset
|
|
|
|
Where:
|
|
|
|
- `list` is a list of usernames as strings
|
|
|
|
- `attrset` is a set of valid users with the name as the key and the path as the value.
|
|
|
|
Example:
|
|
|
|
# Assuming only 'foo-dogsquared' is the existing user.
|
2021-12-06 07:27:51 +00:00
|
|
|
# Get valid users from home-manager.
|
|
|
|
getUsers "home-manager" [ "foo-dogsquared" "archie" "brad" ]
|
2021-11-29 09:58:02 +00:00
|
|
|
=> { foo-dogsquared = /home/foo-dogsquared/projects/nixos-config/users/foo-dogsquared; }
|
|
|
|
*/
|
2021-12-06 07:27:51 +00:00
|
|
|
getUsers = type: users:
|
2021-11-29 05:30:57 +00:00
|
|
|
let
|
2021-12-06 07:27:51 +00:00
|
|
|
userModules = filesToAttr ../users/${type};
|
2021-11-30 01:03:05 +00:00
|
|
|
invalidUsernames = [ "config" "modules" ];
|
|
|
|
in lib.filterAttrs (n: _: !lib.elem n invalidUsernames) userModules;
|
2021-11-29 05:30:57 +00:00
|
|
|
|
2021-11-25 11:55:30 +00:00
|
|
|
/* Create an attribute set from two lists (or a zip).
|
|
|
|
|
2021-11-25 13:45:48 +00:00
|
|
|
Examples:
|
|
|
|
zipToAttrs [ "tails" "breed" ] [ 1 "Doggo" ]
|
|
|
|
=> { tails = 1; breed = "Doggo" }
|
2021-11-25 11:55:30 +00:00
|
|
|
|
2021-11-25 13:45:48 +00:00
|
|
|
zipToAttrs [ "hello" "d" ] [ { r = 5; f = "dogs"; } { r = 532; f = "dogsso"; } ]
|
|
|
|
=> { d = { ... }; hello = { ... }; }
|
2021-11-25 11:55:30 +00:00
|
|
|
*/
|
|
|
|
zipToAttrs = keys: values:
|
2021-11-25 13:45:48 +00:00
|
|
|
lib.listToAttrs
|
|
|
|
(lib.zipListsWith (name: value: { inherit name value; }) keys values);
|
2021-11-25 11:55:30 +00:00
|
|
|
|
|
|
|
/* Count the attributes with the given predicate.
|
|
|
|
|
|
|
|
Examples:
|
|
|
|
countAttrs (name: value: value) { d = true; f = true; a = false; }
|
2021-12-06 07:27:51 +00:00
|
|
|
=> 2
|
|
|
|
|
|
|
|
countAttrs (name: value: value.enable) { d = { enable = true; }; f = { enable = false; package = [ ]; }; }
|
|
|
|
=> 1
|
2021-11-25 11:55:30 +00:00
|
|
|
*/
|
|
|
|
countAttrs = pred: attrs:
|
2021-11-25 13:45:48 +00:00
|
|
|
lib.count (attr: pred attr.name attr.value)
|
|
|
|
(lib.mapAttrsToList lib.nameValuePair attrs);
|
2021-11-25 11:55:30 +00:00
|
|
|
}
|