Module option for Specialisations
To declare specialisations and make them work with nh, we must use the following:
{config, pkgs, ...}: {
specialisation."foo" = {
configuration = {
environment.etc."specialisation".text = "foo";
# ..rest of config
};
};
}
It would be nice to have a wrapper, such that I don't forget to do it:
{config, pkgs, ...}: {
programs.nh.specialisation."foo" = {
inheritParentConfig = true;
configuration = { /* ... */ };
};
}
What kind of an API do you have in mind for this? Does nh create those files by initiating a command on first run (and skip creating on subsequent runs, etc.) or is this a nixos module thing?
Just injecting environment.etc.<name>.text = name; in the specialisation config.
So just through the module system, alright. Should be relatively easy to map nh specializations.
It’s not very obvious at first, but you can centralize this logic into a single module that handles it for all specialisations. The key is to extend the configuration submodule under options.specialisation, rather than extending specialisation.<name>.configuration directly in config. The latter quickly leads to infinite recursion.
Instead, do something like this:
{ lib, ... }:
let
inherit (lib) mkOption types;
named-spec-module = spec: { ... }: {
config = {
environment.etc."specialisation".text = spec;
};
};
in
{
options.specialisation = mkOption {
type = types.attrsOf (types.submodule (
{ name, ... }: {
options.configuration = mkOption {
type = types.submoduleWith { modules = [ (named-spec-module name) ]; };
};
}
));
};
}
It’s not entirely clear to me why the relevant modules in Nixpkgs don’t already inject the attribute names into their corresponding configs. Specialisations do get a name argument in their module scope, but it’s not all that helpful as it's the name of an attribute in a different set. Classic Nix, haha.