From 6c1a0a5d3395c5416d39e67a47bcdf7c1762613e Mon Sep 17 00:00:00 2001 From: _cry64 Date: Tue, 17 Mar 2026 20:37:59 +1000 Subject: [PATCH] minimal working state --- flake.lock | 32 ++--- nix/default.nix | 38 +++--- nix/nixos/default.nix | 10 +- nix/nixos/home.nix | 6 +- nix/snow/default.nix | 21 +-- nix/snow/flake/default.nix | 14 +- nix/snow/flake/module.nix | 24 ---- nix/snow/flake/modules/apps.nix | 2 +- nix/snow/flake/modules/checks.nix | 2 +- nix/snow/flake/modules/devShells.nix | 2 +- nix/snow/flake/modules/formatter.nix | 2 +- nix/snow/flake/modules/legacyPackages.nix | 2 +- nix/snow/flake/modules/outputs.nix | 61 ++++----- nix/snow/flake/modules/packages.nix | 2 +- nix/snow/flake/nodes/default.nix | 4 +- nix/snow/flake/nodes/groups.nix | 73 ----------- nix/snow/flake/nodes/node.nix | 62 +++++---- nix/snow/flake/nodes/nodes.nix | 14 +- nix/snow/flake/outputs/checks.nix | 4 +- nix/snow/flake/outputs/default.nix | 7 + nix/snow/flake/outputs/deploy.nix | 37 +----- .../flake/outputs/nixosConfigurations.nix | 123 +++++++++--------- nix/snow/lib/default.nix | 18 ++- nix/snow/lib/nixpkgs.nix | 7 +- nix/snow/lib/nodes.nix | 87 +++++++++++++ nix/snow/lib/util.nix | 3 + 26 files changed, 331 insertions(+), 326 deletions(-) delete mode 100644 nix/snow/flake/module.nix delete mode 100644 nix/snow/flake/nodes/groups.nix create mode 100644 nix/snow/flake/outputs/default.nix create mode 100644 nix/snow/lib/nodes.nix create mode 100644 nix/snow/lib/util.nix diff --git a/flake.lock b/flake.lock index a8c1976..6f3fefe 100644 --- a/flake.lock +++ b/flake.lock @@ -9,11 +9,11 @@ "utils": "utils" }, "locked": { - "lastModified": 1766051518, - "narHash": "sha256-znKOwPXQnt3o7lDb3hdf19oDo0BLP4MfBOYiWkEHoik=", + "lastModified": 1770019181, + "narHash": "sha256-hwsYgDnby50JNVpTRYlF3UR/Rrpt01OrxVuryF40CFY=", "owner": "serokell", "repo": "deploy-rs", - "rev": "d5eff7f948535b9c723d60cd8239f8f11ddc90fa", + "rev": "77c906c0ba56aabdbc72041bf9111b565cdd6171", "type": "github" }, "original": { @@ -68,11 +68,11 @@ "spectrum": "spectrum" }, "locked": { - "lastModified": 1771365290, - "narHash": "sha256-1XJOslVyF7yzf6yd/yl1VjGLywsbtwmQh3X1LuJcLI4=", + "lastModified": 1773018425, + "narHash": "sha256-fpgZBmZpKoEXEowBK/6m8g9FcOLWQ4UxhXHqCw2CpSM=", "owner": "microvm-nix", "repo": "microvm.nix", - "rev": "789c90b164b55b4379e7a94af8b9c01489024c18", + "rev": "25ebda3c558e923720c965832dc9a04f559a055c", "type": "github" }, "original": { @@ -129,11 +129,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1768323494, - "narHash": "sha256-yBXJLE6WCtrGo7LKiB6NOt6nisBEEkguC/lq/rP3zRQ=", + "lastModified": 1773375660, + "narHash": "sha256-SEzUWw2Rf5Ki3bcM26nSKgbeoqi2uYy8IHVBqOKjX3w=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "2c3e5ec5df46d3aeee2a1da0bfedd74e21f4bf3a", + "rev": "3e20095fe3c6cbb1ddcef89b26969a69a1570776", "type": "github" }, "original": { @@ -166,11 +166,11 @@ "systems": "systems_2" }, "locked": { - "lastModified": 1770975056, - "narHash": "sha256-ZXTz/P3zUbbM6lNXzt91u8EwfNqhXpYMu8+wvFZqQHE=", + "lastModified": 1773738366, + "narHash": "sha256-oH22HyNHEdCoCQo734sQCHUr6C0jmGQJMZ13dsgEHkk=", "owner": "cry128", "repo": "nt", - "rev": "f42dcdd49a7921a7f433512e83d5f93696632412", + "rev": "f32c3a726a3d608d30aaaa1df2301c1eaf5ef8f4", "type": "github" }, "original": { @@ -212,11 +212,11 @@ "spectrum": { "flake": false, "locked": { - "lastModified": 1759482047, - "narHash": "sha256-H1wiXRQHxxPyMMlP39ce3ROKCwI5/tUn36P8x6dFiiQ=", + "lastModified": 1772189877, + "narHash": "sha256-i1p90Rgssb//aNiTDFq46ZG/fk3LmyRLChtp/9lddyA=", "ref": "refs/heads/main", - "rev": "c5d5786d3dc938af0b279c542d1e43bce381b4b9", - "revCount": 996, + "rev": "fe39e122d898f66e89ffa17d4f4209989ccb5358", + "revCount": 1255, "type": "git", "url": "https://spectrum-os.org/git/spectrum" }, diff --git a/nix/default.nix b/nix/default.nix index 6c488a1..6364a63 100644 --- a/nix/default.nix +++ b/nix/default.nix @@ -15,22 +15,28 @@ mix, inputs, ... -} @ args: -mix.newMixture args (mixture: { - submods.public = [ - ./snow - ]; +} @ args: let + mixArgs = + args + // { + inherit (inputs.nixpkgs) lib; + }; +in + mix.newMixture mixArgs (mixture: { + submods.public = [ + ./snow + ]; - version = "0.2.6-alpha"; + version = "0.2.6-alpha"; - overlays = [ - # build deploy-rs as a package not from the flake input, - # hence we can rely on a nixpkg binary cache. - inputs.deploy-rs.overlays.default - ]; + overlays = [ + # build deploy-rs as a package not from the flake input, + # hence we can rely on a nixpkg binary cache. + inputs.deploy-rs.overlays.default + ]; - nixosModules = rec { - default = cerulean; - cerulean = ./nixos; - }; -}) + nixosModules = rec { + default = cerulean; + cerulean = ./nixos; + }; + }) diff --git a/nix/nixos/default.nix b/nix/nixos/default.nix index a716c2f..a91df1a 100644 --- a/nix/nixos/default.nix +++ b/nix/nixos/default.nix @@ -18,13 +18,13 @@ node, pkgs, lib, - _cerulean, + _snow, ... } @ args: { imports = [ - _cerulean.inputs.sops-nix.nixosModules.sops - # _cerulean.inputs.microvm.nixosModules.microvm + _snow.inputs.sops-nix.nixosModules.sops + # _snow.inputs.microvm.nixosModules.microvm # add support for `options.legacyImports` # ./legacy-imports.nix @@ -36,7 +36,7 @@ (import /${root}/nixpkgs.nix) ] # homemanager options declarations - ++ (lib.optional (_cerulean.homeManager != null) ./home.nix) + ++ (lib.optional (_snow.homeManager != null) ./home.nix) # remote deployment configuration ++ (lib.optional (node.deploy.ssh.host != null) ./remote-deploy); @@ -46,7 +46,7 @@ (with pkgs; [ sops ]) - ++ (with _cerulean.inputs; [ + ++ (with _snow.inputs; [ deploy-rs.packages.${system}.default ]); } diff --git a/nix/nixos/home.nix b/nix/nixos/home.nix index 82117d8..cf24f74 100644 --- a/nix/nixos/home.nix +++ b/nix/nixos/home.nix @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. { - _cerulean, + _snow, config, root, lib, @@ -30,7 +30,7 @@ ; in { imports = [ - _cerulean.homeManager.nixosModules.default + _snow.homeManager.nixosModules.default ]; options = { @@ -69,7 +69,7 @@ in { _module.args.username = name; }); - extraSpecialArgs = _cerulean.specialArgs; + extraSpecialArgs = _snow.specialArgs; sharedModules = [ ../home diff --git a/nix/snow/default.nix b/nix/snow/default.nix index 5f95f46..89e1772 100644 --- a/nix/snow/default.nix +++ b/nix/snow/default.nix @@ -11,12 +11,17 @@ # 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. -{mix, ...} @ args: -mix.newMixture args (mixture: { - includes = { - public = [ - ./flake - ./lib - ]; - }; +{ + nt, + mix, + ... +} @ args: +mix.newMixture (removeAttrs args ["this"]) (mixture: { + submods.public = [ + ./lib + ]; + + includes.public = [ + ./flake + ]; }) diff --git a/nix/snow/flake/default.nix b/nix/snow/flake/default.nix index 9c5d1f5..828f59b 100644 --- a/nix/snow/flake/default.nix +++ b/nix/snow/flake/default.nix @@ -1,4 +1,5 @@ { + self, this, inputs, systems, @@ -16,14 +17,20 @@ inherit (inputs.nixpkgs) lib; in { # snow.flake + # XXX: TODO: stop taking in root as parameter (maybe take self instead?) flake = flakeInputs: root: let snowflake = lib.evalModules { class = "snowflake"; specialArgs = let reservedSpecialArgs = { - inherit (this) snow; + # inherit (this) snow; + snow = this; inherit systems root; inputs = flakeInputs; + + _snowFlake = { + inherit self inputs; + }; }; warnIfReserved = let @@ -50,7 +57,10 @@ in { flakeInputs // reservedSpecialArgs; modules = [ - ./module.nix + ./nodes + ./modules + ./outputs + (this.lib.findImport /${root}/snow) ]; }; in diff --git a/nix/snow/flake/module.nix b/nix/snow/flake/module.nix deleted file mode 100644 index 1aacd0b..0000000 --- a/nix/snow/flake/module.nix +++ /dev/null @@ -1,24 +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. -{ - root, - snow, - ... -}: { - imports = [ - ./nodes - ./modules - (snow.findImport /${root}/snow) - ]; -} diff --git a/nix/snow/flake/modules/apps.nix b/nix/snow/flake/modules/apps.nix index 75cc4be..cbe12f0 100644 --- a/nix/snow/flake/modules/apps.nix +++ b/nix/snow/flake/modules/apps.nix @@ -10,7 +10,7 @@ ; inherit - (snow) + (snow.lib) mkPerSystemFlakeOutput ; diff --git a/nix/snow/flake/modules/checks.nix b/nix/snow/flake/modules/checks.nix index a8a7280..d10d6d5 100644 --- a/nix/snow/flake/modules/checks.nix +++ b/nix/snow/flake/modules/checks.nix @@ -9,7 +9,7 @@ types ; inherit - (snow) + (snow.lib) mkPerSystemFlakeOutput ; in diff --git a/nix/snow/flake/modules/devShells.nix b/nix/snow/flake/modules/devShells.nix index 7116e6b..04ace01 100644 --- a/nix/snow/flake/modules/devShells.nix +++ b/nix/snow/flake/modules/devShells.nix @@ -10,7 +10,7 @@ literalExpression ; inherit - (snow) + (snow.lib) mkPerSystemFlakeOutput ; in diff --git a/nix/snow/flake/modules/formatter.nix b/nix/snow/flake/modules/formatter.nix index 44e07c2..5cce36b 100644 --- a/nix/snow/flake/modules/formatter.nix +++ b/nix/snow/flake/modules/formatter.nix @@ -9,7 +9,7 @@ types ; inherit - (snow) + (snow.lib) mkPerSystemFlakeOutput ; in diff --git a/nix/snow/flake/modules/legacyPackages.nix b/nix/snow/flake/modules/legacyPackages.nix index f167c93..9adc91d 100644 --- a/nix/snow/flake/modules/legacyPackages.nix +++ b/nix/snow/flake/modules/legacyPackages.nix @@ -9,7 +9,7 @@ types ; inherit - (snow) + (snow.lib) mkPerSystemFlakeOutput ; in diff --git a/nix/snow/flake/modules/outputs.nix b/nix/snow/flake/modules/outputs.nix index 551186a..bf7d9f5 100644 --- a/nix/snow/flake/modules/outputs.nix +++ b/nix/snow/flake/modules/outputs.nix @@ -8,38 +8,39 @@ mkOption types ; - - outputs = mkOption { - type = types.submoduleWith { - modules = [ - { - freeformType = - types.lazyAttrsOf - (types.unique - { - message = '' - No option has been declared for this flake output attribute, so its definitions can't be merged automatically. - Possible solutions: - - Load a module that defines this flake output attribute - - Declare an option for this flake output attribute - - Make sure the output attribute is spelled correctly - - Define the value only once, with a single definition in a single module - ''; - } - types.raw); - } - ]; - }; - description = '' - Raw flake output attributes. Any attribute can be set here, but some - attributes are represented by options, to provide appropriate - configuration merging. - ''; - }; in { options = { - inherit outputs; + outputs = mkOption { + type = types.submoduleWith { + modules = [ + { + freeformType = + types.lazyAttrsOf + (types.unique + { + message = '' + No option has been declared for this flake output attribute, so its definitions can't be merged automatically. + Possible solutions: + - Load a module that defines this flake output attribute + - Declare an option for this flake output attribute + - Make sure the output attribute is spelled correctly + - Define the value only once, with a single definition in a single module + ''; + } + types.raw); + } + ]; + }; + description = '' + Raw flake output attributes. Any attribute can be set here, but some + attributes are represented by options, to provide appropriate + configuration merging. + ''; + }; }; - config = {inherit (config) flake;}; + config = { + # ensure a minimal version is set + outputs = {}; + }; } diff --git a/nix/snow/flake/modules/packages.nix b/nix/snow/flake/modules/packages.nix index 517c758..ef970bc 100644 --- a/nix/snow/flake/modules/packages.nix +++ b/nix/snow/flake/modules/packages.nix @@ -10,7 +10,7 @@ ; inherit - (snow) + (snow.lib) mkPerSystemFlakeOutput ; in diff --git a/nix/snow/flake/nodes/default.nix b/nix/snow/flake/nodes/default.nix index d7b6a82..07ad153 100644 --- a/nix/snow/flake/nodes/default.nix +++ b/nix/snow/flake/nodes/default.nix @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. { - _snow, + _snowFlake, lib, specialArgs, ... @@ -39,7 +39,7 @@ config = { nodes = { - base = _snow.inputs.nixpkgs; + base = _snowFlake.inputs.nixpkgs; }; }; } diff --git a/nix/snow/flake/nodes/groups.nix b/nix/snow/flake/nodes/groups.nix deleted file mode 100644 index b22cac0..0000000 --- a/nix/snow/flake/nodes/groups.nix +++ /dev/null @@ -1,73 +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"; -in { - parseGroupsDecl = groups: let - validGroup = g: - isAttrs g - || throw '' - Snow node groups must be provided as attribute sets, got "${typeOf g}" instead! - Ensure all the group definitions are attribute sets under your call to `snow.flake`. - 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; -} diff --git a/nix/snow/flake/nodes/node.nix b/nix/snow/flake/nodes/node.nix index a368d24..11c2b98 100644 --- a/nix/snow/flake/nodes/node.nix +++ b/nix/snow/flake/nodes/node.nix @@ -14,8 +14,9 @@ { lib, systems, - config, nodesConfig, + groups, + groupLibs, ... }: { options = let @@ -25,6 +26,11 @@ types ; + inherit + (groupLibs) + resolveGroupsInheritance + ; + flakeRef = types.either types.str types.path; in { enabled = lib.mkOption { @@ -113,8 +119,8 @@ A function from the `groups` hierarchy to a list of groups this node inherits from. ''; - apply = groupsFn: - groupsFn nodesConfig.groups; + # apply = groupsFn: + # groupsFn nodesConfig.groups |> resolveGroupsInheritance; }; deploy = { @@ -266,32 +272,32 @@ }; }; - config = let - throwGotNull = name: - throw '' - [snow] `nodes..${name}` must be set for all nodes! (got: ) - ''; - givenSystem = - (config.system != null) - || throwGotNull "system"; + # config = let + # throwGotNull = name: + # throw '' + # [snow] `nodes..${name}` must be set for all nodes! (got: ) + # ''; + # givenSystem = + # (config.system != null) + # || throwGotNull "system"; - givenBase = - (config.base != null) - || throwGotNull "base"; + # givenBase = + # (config.base != null) + # || throwGotNull "base"; - givenHomeManager = - (config.homeManager != null) - || throwGotNull "homeManager"; + # givenHomeManager = + # (config.homeManager != null) + # || throwGotNull "homeManager"; - givenDeployHost = - (config.deploy.ssh.host != null) - || throwGotNull "deploy.ssh.host"; - in - assert givenSystem - && givenBase - && givenHomeManager - && givenDeployHost; { - # extend these from the nodes configuration - inherit (nodesConfig) modules args; - }; + # givenDeployHost = + # (config.deploy.ssh.host != null) + # || throwGotNull "deploy.ssh.host"; + # in + # assert givenSystem + # && givenBase + # && givenHomeManager + # && givenDeployHost; { + # # extend these from the nodes configuration + # inherit (nodesConfig) modules args; + # }; } diff --git a/nix/snow/flake/nodes/nodes.nix b/nix/snow/flake/nodes/nodes.nix index 58a9e1a..d5e5a59 100644 --- a/nix/snow/flake/nodes/nodes.nix +++ b/nix/snow/flake/nodes/nodes.nix @@ -12,7 +12,9 @@ # See the License for the specific language governing permissions and # limitations under the License. { - _snow, + _snowFlake, + snow, + root, lib, config, specialArgs, @@ -26,7 +28,10 @@ flakeRef = types.either types.str types.path; - groupLibs = import ./groups.nix {inherit (_snow.inputs) nt;}; + groupLibs = import ./groups.nix { + inherit snow root; + inherit (_snowFlake.inputs) nt; + }; in { options = { base = lib.mkOption { @@ -94,8 +99,6 @@ in { description = '' Hierarchical groups that nodes can be a member of. ''; - - apply = groupLibs.parseGroupsDecl; }; nodes = mkOption { @@ -103,7 +106,8 @@ in { specialArgs = specialArgs // { - nodeConfig = config; + nodesConfig = config; + inherit groupLibs; }; modules = [./node.nix]; }); diff --git a/nix/snow/flake/outputs/checks.nix b/nix/snow/flake/outputs/checks.nix index a25ba32..de6a9c0 100644 --- a/nix/snow/flake/outputs/checks.nix +++ b/nix/snow/flake/outputs/checks.nix @@ -1,10 +1,10 @@ { config, - _snow, + _snowFlake, ... }: { outputs.checks = - _snow.inputs.deploy-rs.lib + _snowFlake.inputs.deploy-rs.lib |> builtins.mapAttrs (system: deployLib: deployLib.deployChecks config.outputs.deploy); } diff --git a/nix/snow/flake/outputs/default.nix b/nix/snow/flake/outputs/default.nix new file mode 100644 index 0000000..2c0a9ca --- /dev/null +++ b/nix/snow/flake/outputs/default.nix @@ -0,0 +1,7 @@ +{...}: { + imports = [ + ./checks.nix + ./deploy.nix + ./nixosConfigurations.nix + ]; +} diff --git a/nix/snow/flake/outputs/deploy.nix b/nix/snow/flake/outputs/deploy.nix index c8d39a9..59bbb49 100644 --- a/nix/snow/flake/outputs/deploy.nix +++ b/nix/snow/flake/outputs/deploy.nix @@ -1,37 +1,10 @@ { - _snow, + _snowFlake, + snow, config, ... -}: let - inherit - (builtins) - mapAttrs - ; - - 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 '' - snow 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; - }); -in { - outputs.deploy.nodes = mapNodes config.nodes ({ +}: { + outputs.deploy.nodes = snow.lib.mapNodes config.nodes ({ name, node, ... @@ -49,7 +22,7 @@ in { confirmTimeout ; - nixosFor = system: _snow.inputs.deploy-rs.lib.${system}.activate.nixos; + nixosFor = system: _snowFlake.inputs.deploy-rs.lib.${system}.activate.nixos; in { hostname = if ssh.host != null diff --git a/nix/snow/flake/outputs/nixosConfigurations.nix b/nix/snow/flake/outputs/nixosConfigurations.nix index 2ca88b6..977fa22 100644 --- a/nix/snow/flake/outputs/nixosConfigurations.nix +++ b/nix/snow/flake/outputs/nixosConfigurations.nix @@ -1,14 +1,5 @@ -# { -# _module = { ... }; -# _type = "configuration"; -# class = null; -# config = { ... }; -# extendModules = «lambda extendModules @ /nix/store/9hfp0agnm43kz72l5lpfn9var5p0x2fa-source/lib/modules.nix:340:9»; -# graph = [ ... ]; -# options = { ... }; -# type = { ... }; -# } { + _snowFlake, snow, config, systems, @@ -27,59 +18,67 @@ nodes ; in { - outputs.nixosConfigurations = mapNodes nodes ( - { - base, - lib, - name, - node, - groupModules, - ... - }: let - homeManager = - if node.homeManager != null - then node.homeManager - else if nodes.homeManager != null - then nodes.homeManager - else - warn '' - [snowflake] Neither `nodes.homeManager` nor `nodes.nodes.${name}.homeManager` were specified! - [snowflake] home-manager will NOT be used! User configuration will be ignored! - '' - null; + outputs.nixosConfigurations = let + groups = snow.lib.parseGroupDecls root config.nodes.groups; + in + snow.lib.mapNodes nodes ( + { + base, + lib, + name, + node, + ... + }: let + nodeGroups = + (node.groups groups) + |> snow.lib.resolveGroupsInheritance + |> snow.lib.groupModules; - userArgs = nodes.args // node.args; - snowArgs = { - inherit systems snow root base nodes node; - inherit (node) system; - hostname = name; + homeManager = + if node.homeManager != null + then node.homeManager + else if nodes.homeManager != null + then nodes.homeManager + else + warn '' + [snowflake] Neither `nodes.homeManager` nor `nodes.nodes.${name}.homeManager` were specified! + [snowflake] home-manager will NOT be used! User configuration will be ignored! + '' + null; - _snow = { - inherit inputs userArgs snowArgs homeManager; - specialArgs = userArgs // snowArgs; + userArgs = nodes.args // node.args; + snowArgs = { + inherit systems snow root base nodes node; + inherit (node) system; + hostname = name; + + _snow = { + inherit (_snowFlake) inputs; + inherit userArgs snowArgs homeManager; + specialArgs = userArgs // snowArgs; + }; }; - }; - specialArgs = assert (userArgs - |> attrNames - |> all (argName: - ! snowArgs ? argName - || abort '' - `specialArgs` are like super important to Snow my love... attrNames + |> all (argName: + ! snowArgs ? argName + || abort '' + `specialArgs` are like super important to Snow my love... = 0) || abort '' The nixpkgs dependency of snow was overridden but is too old. The minimum supported version of nixpkgs-lib is ${minVersion}, diff --git a/nix/snow/lib/nodes.nix b/nix/snow/lib/nodes.nix new file mode 100644 index 0000000..6f799cf --- /dev/null +++ b/nix/snow/lib/nodes.nix @@ -0,0 +1,87 @@ +{ + this, + nt, + ... +}: let + inherit + (builtins) + concatLists + elem + filter + isAttrs + mapAttrs + pathExists + typeOf + ; + + inherit (nt.prim) uniq; + + rootGroupName = "all"; +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 '' + snow 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; + + inherit (node) groups; + }); + + groupModules = map (group: group._module); + + parseGroupDecls = root: groupDecls: let + validGroup = g: + isAttrs g + || throw '' + Snow node groups must be provided as attribute sets, got "${typeOf g}" instead! + Ensure all the group definitions are attribute sets under your call to `snow.flake`. + ''; + delegate = parent: gName: g: let + result = + (g + // { + _name = gName; + _parent = parent; + _module = this.lib.findImport /${root}/groups/${gName}; + }) + |> mapAttrs (name: value: + if elem name ["_name" "_parent" "_module"] + # ignore metadata fields + then value + else assert validGroup value; (delegate result name value)); + in + result; + in + assert validGroup groupDecls; + delegate null rootGroupName groupDecls; + + resolveGroupsInheritance = groups: + 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 + # ignore missing groups + |> filter (group: pathExists group._module) + # filter by uniqueness + |> uniq; +} diff --git a/nix/snow/lib/util.nix b/nix/snow/lib/util.nix new file mode 100644 index 0000000..6bfcd17 --- /dev/null +++ b/nix/snow/lib/util.nix @@ -0,0 +1,3 @@ +{nt, ...}: { + inherit (nt) findImport; +}