Add gen to a Flake
You can bring gen into a flake in two ways. Take one library’s .lib when you need one
feature. Import the hub’s flake-parts module when you want a gen module tree built into
nixosConfigurations.
{ inputs.gen-graph.url = "github:sini/gen-graph";
outputs = { gen-graph, ... }: let graph = gen-graph.lib; in { # use graph.reachableFrom, graph.roots, ... directly };}A flake that reads inputs.gen-<name>.lib does not need the hub. Without flakes,
import ./gen-graph { } on a checkout returns the same library, with its dependencies read
from its own flake.lock. Getting Started is a complete example.
{ inputs = { gen.url = "github:sini/gen"; nixpkgs.follows = "gen/nixpkgs"; flake-parts.url = "github:hercules-ci/flake-parts"; flake-parts.inputs.nixpkgs-lib.follows = "nixpkgs"; };
outputs = inputs: inputs.flake-parts.lib.mkFlake { inherit inputs; } { imports = [ inputs.gen.flakeModules.default ]; # (1) systems = [ "x86_64-linux" ];
gen = { tree = ./gen-modules; # (2) aspectCnf = import ./aspect-cnf.nix; # (3) nodeRegistryPath = [ "hosts" ]; # (4) extraModules.web = [ ./hardware/web.nix ]; # (5) }; };}- The hub’s flake-parts module. It composes the tree and sets
flake.nixosConfigurations. - A directory of gen modules. The
.nixfiles in it are loaded as gen modules. - The declaration of which aspect keys are classes. The tree reads the same file.
- Required. The attribute path of the registry whose members become systems.
- NixOS modules added to one system, such as its hardware configuration.
From an Aspect to a NixOS System fills in gen-modules/ and
builds the systems.
The hub options
Section titled “The hub options”inputs.gen.flakeModules.default declares these options under gen:
| option | default | what it sets |
|---|---|---|
tree | null | A directory of gen modules. They are merged by gen’s own module system, gen-merge, and never by nixpkgs. |
modules | [ ] | More gen modules, added to the tree. |
specialArgs | { } | Extra module arguments for the tree, merged over the gen libraries the hub passes in. |
aspectCnf | none | The mkAspectSchema argument: which aspect keys are classes, such as nixos, and which are channels. Required. Without it the build fails with an error. |
nodeRegistryPath | none | The attribute path, in the composed values, of the registry holding the systems to build, for example [ "hosts" ] or [ "fleet" "hosts" ]. Required. A missing path fails with an error listing the top-level keys. A wrong path fails with an error naming the segment it could not find and the keys present beside it. |
extraModules.<node> | { } | NixOS modules added to one node’s system. A node with no nixos content fails with an error. Key this from your own node list, never from nixosConfigurations. |
nixpkgs | inputs.nixpkgs | The nixpkgs whose lib.nixosSystem builds each system. null removes the default nixos terminal. |
terminals | { } | One terminal per class: the function that turns a node’s modules into a built artifact. A default nixos terminal is added unless you supply one. |
inject | { genValues = …; } | Values passed to your flake-parts modules as module arguments. |
injectPerSystem | false | Also pass inject to every perSystem module. |
Two read-only values let you look at the result: gen.composed (the composed values) and
gen.realized (every built artifact, keyed by class and node). flake.nixosConfigurations
is gen.realized.nixos.
Name one registry in nodeRegistryPath. To build systems from several registries, declare
an option in your tree that merges them with mkMerge, and name that option’s path.
Module arguments
Section titled “Module arguments”Modules in gen.tree receive the gen libraries they build with: genMerge, genSchema,
genAspects, genTypes and genPrelude. Add others through gen.specialArgs.
Your ordinary flake-parts modules receive the composed values as genValues:
{ genValues, ... }:{ flake.hostNames = builtins.attrNames genValues.hosts;}To get library arguments in your flake-parts modules too, import
inputs.gen.flakeModules.genLibs. It adds genAlgebra, genSchema, genAspects,
genScope, genGraph, genSelect, genBind and genDispatch.
The whole library set
Section titled “The whole library set”inputs.gen.lib.mkGenLibs { } returns every gen library under a short name:
graph, merge, schema, aspects, program and the rest. Each value is the same as
inputs.gen-<name>.lib.
let gen = inputs.gen.lib.mkGenLibs { }; ingen.graph.reachableFrom g "web"An outputs terminal over flake-parts
Section titled “An outputs terminal over flake-parts”A terminal can build flake outputs as well as NixOS systems. gen-bind’s
crossing.mkOutputsTerminal takes an evaluate function. The hub’s
lib.flakePartsEvaluate is that function for flake-parts:
genBind.crossing.mkOutputsTerminal (inputs.gen.lib.flakePartsEvaluate { inherit (inputs.flake-parts.lib) evalFlakeModule; inherit inputs self; systems = [ "x86_64-linux" ];})Palettes adapted from Catppuccin (Macchiato) (MIT), Tokyo Night (Apache-2.0), gruvbox (MIT), Catppuccin (Latte) (MIT), Rosé Pine (Dawn) (MIT).