123 lines
3.2 KiB
Nix
123 lines
3.2 KiB
Nix
{ lib, clanLib }:
|
|
let
|
|
# Trim the .nix extension from a filename
|
|
trimExtension = name: builtins.substring 0 (builtins.stringLength name - 4) name;
|
|
|
|
jsonWithoutHeader = clanLib.jsonschema {
|
|
includeDefaults = true;
|
|
header = { };
|
|
};
|
|
|
|
getModulesSchema =
|
|
{
|
|
modules,
|
|
clan-core,
|
|
pkgs,
|
|
}:
|
|
lib.mapAttrs
|
|
(
|
|
_moduleName: rolesOptions:
|
|
lib.mapAttrs (_roleName: options: jsonWithoutHeader.parseOptions options { }) rolesOptions
|
|
)
|
|
(
|
|
clanLib.evalClan.evalClanModulesWithRoles {
|
|
allModules = modules;
|
|
inherit pkgs clan-core;
|
|
}
|
|
);
|
|
|
|
evalFrontmatter =
|
|
{
|
|
moduleName,
|
|
instanceName,
|
|
resolvedRoles,
|
|
allModules,
|
|
}:
|
|
lib.evalModules {
|
|
specialArgs = {
|
|
inherit moduleName resolvedRoles instanceName;
|
|
allRoles = getRoles allModules moduleName;
|
|
};
|
|
modules = [
|
|
(getFrontmatter allModules.${moduleName} moduleName)
|
|
./interface.nix
|
|
];
|
|
};
|
|
|
|
# For Documentation purposes only
|
|
frontmatterOptions =
|
|
(lib.evalModules {
|
|
specialArgs = {
|
|
moduleName = "{moduleName}";
|
|
allRoles = [ "{roleName}" ];
|
|
};
|
|
modules = [
|
|
./interface.nix
|
|
];
|
|
}).options;
|
|
|
|
getRoles =
|
|
allModules: serviceName:
|
|
lib.mapAttrsToList (name: _value: trimExtension name) (
|
|
lib.filterAttrs (name: type: type == "regular" && lib.hasSuffix ".nix" name) (
|
|
builtins.readDir (
|
|
if allModules ? ${serviceName} then
|
|
allModules.${serviceName} + "/roles"
|
|
else
|
|
throw "ClanModule not found: '${serviceName}'. Make sure the module is added in the 'clanModules' attribute of clan-core."
|
|
)
|
|
)
|
|
);
|
|
|
|
checkConstraints = args: (evalFrontmatter args).config.constraints.assertions;
|
|
|
|
getReadme =
|
|
modulepath: modulename:
|
|
let
|
|
readme = modulepath + "/README.md";
|
|
readmeContents =
|
|
if (builtins.pathExists readme) then
|
|
(builtins.readFile readme)
|
|
else
|
|
throw "No README.md found for module ${modulename} (expected at ${readme})";
|
|
in
|
|
readmeContents;
|
|
|
|
getFrontmatter =
|
|
modulepath: modulename:
|
|
let
|
|
content = getReadme modulepath modulename;
|
|
parts = lib.splitString "---" content;
|
|
# Partition the parts into the first part (the readme content) and the rest (the metadata)
|
|
parsed = builtins.partition ({ index, ... }: if index >= 2 then false else true) (
|
|
lib.filter ({ index, ... }: index != 0) (lib.imap0 (index: part: { inherit index part; }) parts)
|
|
);
|
|
meta = builtins.fromTOML (builtins.head parsed.right).part;
|
|
in
|
|
if (builtins.length parts >= 3) then
|
|
meta
|
|
else
|
|
throw ''
|
|
TOML Frontmatter not found in README.md for module ${modulename}
|
|
|
|
Please add the following to the top of your README.md:
|
|
|
|
---
|
|
description = "Your description here"
|
|
categories = [ "Your categories here" ]
|
|
features = [ "inventory" ]
|
|
---
|
|
...rest of your README.md...
|
|
'';
|
|
in
|
|
{
|
|
inherit
|
|
frontmatterOptions
|
|
getModulesSchema
|
|
getFrontmatter
|
|
|
|
checkConstraints
|
|
getRoles
|
|
;
|
|
}
|