node inheritance + group parsing

This commit is contained in:
do butterflies cry? 2026-03-15 01:10:36 +10:00
parent d891a92357
commit f819933c8d
Signed by: cry
GPG key ID: F68745A836CA0412
12 changed files with 422 additions and 253 deletions

27
nix/snow/lib/default.nix Normal file
View file

@ -0,0 +1,27 @@
# Copyright 2025-2026 _cry64 (Emile Clark-Boman)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
{
nt,
mix,
...
} @ args: let
inherit (nt) findImport;
in
mix.newMixture args (mixture: {
includes.public = [
./nixpkgs.nix
];
inherit findImport;
})

51
nix/snow/lib/nixpkgs.nix Normal file
View file

@ -0,0 +1,51 @@
{
inputs,
lib,
...
}: let
inherit
(lib)
mkOption
types
;
# A best effort, lenient estimate. Please use a recent nixpkgs lib if you
# override it at all.
minVersion = "23.05pre-git";
isNixpkgsValidVersion = let
revInfo = lib.optional (inputs.nixpkgs?rev) " (nixpkgs-lib.rev: ${inputs.nixpkgs.rev})";
in
(builtins.compareVersions lib.version minVersion < 0)
|| abort ''
The nixpkgs dependency of snow was overridden but is too old.
The minimum supported version of nixpkgs-lib is ${minVersion},
but the actual version is ${lib.version}${revInfo}.
'';
in
assert isNixpkgsValidVersion; {
# Helper function for defining a per-system option that
# gets transposed by the usual flake system logic to a
# top-level outputs attribute.
mkPerSystemFlakeOutput = {
name,
option,
file,
}: {
_file = file;
options = {
outputs.${name} = mkOption {
type = types.attrsWith {
elemType = option.type;
lazy = true;
placeholder = "system";
};
default = {};
description = ''
See {option}`perSystem.${name}` for description and examples.
'';
};
};
};
}

View file

@ -1,96 +0,0 @@
# Copyright 2025-2026 _cry64 (Emile Clark-Boman)
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
{nt, ...}: let
inherit
(builtins)
concatLists
elem
filter
isAttrs
mapAttrs
pathExists
typeOf
;
rootGroupName = "all";
parseGroupsDecl = groups: let
validGroup = g:
isAttrs g
|| throw ''
Cerulean Nexus groups must be provided as attribute sets, got "${typeOf g}" instead!
Ensure all the group definitions are attribute sets under your call to `cerulean.mkNexus`.
NOTE: Groups can be accessed via `self.groups.PATH.TO.YOUR.GROUP`
'';
delegate = parent: gName: g: let
result =
(g
// {
_name = gName;
_parent = parent;
})
|> mapAttrs (name: value:
if elem name ["_name" "_parent"]
# ignore metadata fields
then value
else assert validGroup value; (delegate result name value));
in
result;
in
assert validGroup groups;
delegate null rootGroupName groups;
getGroupModules = root: groups:
# ensure root group is always added
groups
# add all inherited groups via _parent
|> map (let
delegate = g:
if g._parent == null
then [g]
else [g] ++ delegate (g._parent);
in
delegate)
# flatten recursion result
|> concatLists
# find import location
|> map (group: nt.findImport /${root}/groups/${group._name})
# filter by uniqueness
|> nt.prim.unique
# ignore missing groups
|> filter pathExists;
in {
mapNodes = nodes: f:
nodes.nodes
|> mapAttrs (name: node: let
# use per-node base or default to nodes' base
base =
if node.base != null
then node.base
else if nodes.base != null
then nodes.base
else
abort ''
Cerulean cannot construct nodes node "${name}" without a base package source.
Ensure `nodes.nodes.*.base` or `nodes.base` is a flake reference to the github:NixOS/nixpkgs repository.
'';
in
f rec {
inherit name node base;
inherit (base) lib;
groups = node.groups (parseGroupsDecl nodes.groups);
groupModules = root: getGroupModules root groups;
});
}