feat(lib)!: add createThings

Redefine `createPackages` and `createModules` in terms of `createThings`
Move `lib` flake module to a subdirectory
This commit is contained in:
reo101 2024-08-04 02:52:04 +03:00
parent cd148400bf
commit 7cf980d913
Signed by: reo101
GPG key ID: 675AA7EF13964ACB
5 changed files with 135 additions and 119 deletions

View file

@ -12,7 +12,7 @@
]; ];
imports = [ imports = [
./modules/flake/lib.nix ./modules/flake/lib
./modules/flake/pkgs ./modules/flake/pkgs
./modules/flake/modules ./modules/flake/modules
./modules/flake/configurations ./modules/flake/configurations

View file

@ -1,6 +1,10 @@
{ lib, config, self, ... }: { lib, config, self, ... }:
{ {
imports = [
./things.nix
];
options = let options = let
inherit (lib) types; inherit (lib) types;
in { in {

View file

@ -0,0 +1,112 @@
{ lib, config, self, inputs, ... }:
let
inherit (config.lib)
and
eq
hasFiles
;
in
{
config.lib = rec {
# Try to passthru `inputs` by default
defaultThingHandle = { raw, thingType }: name: result: let
thing =
if raw
then result
else result.${thingType};
passthru = {
inherit inputs;
};
handledThing =
if and [
(builtins.isFunction
thing)
# FIXME: check for subset, not `eq`
(eq
(lib.pipe thing [ builtins.functionArgs builtins.attrNames ])
(lib.pipe passthru [ builtins.attrNames ]))
]
# { inputs, ... }: { foo, ... }: bar
then thing passthru
# { foo, ... }: bar
else thing;
handledResult =
if raw
then handledThing
else result // { ${thingType} = handledThing; };
in handledResult;
# TODO: make `passthru` more generic (maybe take `thing` as arg and decide itself what to do?)
createThings =
{ baseDir
, thingType ? "thing"
, filter ? (name: type: true)
, handle ? (defaultThingHandle { inherit raw thingType; })
, raw ? true
, extras ? {}
, ...
}:
assert raw -> extras == {};
lib.pipe baseDir [
# Read given directory
builtins.readDir
# Filter out unwanted things
(lib.filterAttrs
filter)
# Map each entry to a thing
(lib.mapAttrs'
(name: type:
let
# BUG: cannot use `append` because of `${self}` (not a path)
# thingDir = lib.path.append baseDir "${name}";
thingDir = "${baseDir}/${name}";
importedExtras = lib.pipe extras [
(lib.mapAttrs (name: { default, ... }:
assert name != "default";
assert name != thingType;
let
extraPath = "${thingDir}/${name}.nix";
in
if builtins.pathExists extraPath
then import extraPath
else default))
];
thing = import thingDir;
result =
if raw
then thing
else lib.attrsets.unionOfDisjoint
{ ${thingType} = thing; }
importedExtras;
in
if and [
(type == "directory")
(hasFiles [ "default.nix" ] (builtins.readDir thingDir))
] then
# Classic thing in a directory
lib.nameValuePair
name
result
else if and [
(type == "regular")
(lib.hasSuffix ".nix" name)
] then
# Classic thing in a file
lib.nameValuePair
(lib.removeSuffix ".nix" name)
result
else
# Invalid thing
lib.nameValuePair
name
null))
# Filter invalid things
(lib.filterAttrs
(thingName: thing:
thing != null))
# Handle if needed
(lib.mapAttrs handle)
];
};
}

View file

@ -2,66 +2,18 @@
let let
inherit (config.lib) inherit (config.lib)
eq createThings
and
hasFiles
configuration-type-to-outputs-modules; configuration-type-to-outputs-modules;
in in
let let
# Modules helpers # Modules helpers
moduleTypes = ["nixos" "nix-on-droid" "nix-darwin" "home-manager" "flake"]; moduleTypes = ["nixos" "nix-on-droid" "nix-darwin" "home-manager" "flake"];
createModules = baseDir: { passthru ? { inherit inputs; }, ... }: createModules = baseDir:
lib.pipe baseDir [ createThings {
# Read given directory inherit baseDir;
builtins.readDir thingType = "module";
# Map each entry to a module };
(lib.mapAttrs'
(name: type:
let
# BUG: cannot use `append` because of `${self}` (not a path)
# moduleDir = lib.path.append baseDir "${name}";
moduleDir = "${baseDir}/${name}";
in
if and [
(type == "directory")
(hasFiles [ "default.nix" ] (builtins.readDir moduleDir))
] then
# Classic module in a directory
lib.nameValuePair
name
(import moduleDir)
else if and [
(type == "regular")
(lib.hasSuffix ".nix" name)
] then
# Classic module in a file
lib.nameValuePair
(lib.removeSuffix ".nix" name)
(import moduleDir)
else
# Invalid module
lib.nameValuePair
name
null))
# Filter invalid modules
(lib.filterAttrs
(moduleName: module:
module != null))
# Passthru if needed
(lib.mapAttrs
(moduleName: module:
if and [
(builtins.isFunction
module)
# FIXME: check for subset, not `eq`
(eq
(lib.pipe module [ builtins.functionArgs builtins.attrNames ])
(lib.pipe passthru [ builtins.attrNames ]))
]
then module passthru
else module))
];
in in
{ {
options = let options = let
@ -115,7 +67,7 @@ in
default = default =
lib.optionalAttrs lib.optionalAttrs
config.flake.autoModules.${moduleType}.enable config.flake.autoModules.${moduleType}.enable
(createModules config.flake.autoModules.${moduleType}.dir { }); (createModules config.flake.autoModules.${moduleType}.dir);
}; };
}; };
}; };

View file

@ -2,70 +2,18 @@
let let
inherit (config.lib) inherit (config.lib)
eq createThings;
and
hasFiles;
in in
let let
createPackages = baseDir: { passthru ? { inherit inputs; }, ... }: createPackages = baseDir:
lib.pipe baseDir [ createThings {
# Read given directory inherit baseDir;
builtins.readDir thingType = "package";
# Map each entry to a package raw = false;
(lib.mapAttrs' extras.systems = {
(name: type: default = lib.const true;
let };
packageDir = "${baseDir}/${name}"; };
systems = let
systemsPath = "${baseDir}/${name}/systems.nix";
in
# NOTE: If the package can restrict for which systems it wants to be built
if builtins.pathExists systemsPath
then import systemsPath
else lib.const true;
package = import packageDir;
result = {
inherit package systems;
};
in
if and [
(type == "directory")
(hasFiles [ "default.nix" ] (builtins.readDir packageDir))
] then
# NOTE: Classic package in a directory
lib.nameValuePair
name
result
else if and [
(type == "regular")
(lib.hasSuffix ".nix" name)
] then
# NOTE: Classic package in a file
lib.nameValuePair
(lib.removeSuffix ".nix" name)
result
else
# NOTE: Invalid package
lib.nameValuePair
name
null))
# Filter invalid packages
(lib.filterAttrs
(packageName: package:
package != null))
# Passthru if needed
(lib.mapAttrs
(packageName: package:
if and [
(builtins.isFunction
package)
(eq
(lib.pipe package [ builtins.functionArgs builtins.attrNames ])
(lib.pipe passthru [ builtins.attrNames ]))
]
then package passthru
else package))
];
in in
{ {
options = let options = let
@ -99,7 +47,7 @@ in
default = default =
lib.optionalAttrs lib.optionalAttrs
config.flake.autoPackages.enable config.flake.autoPackages.enable
(createPackages config.flake.autoPackages.dir { }); (createPackages config.flake.autoPackages.dir);
}; };
}; };
}); });