Splitting Modules¶
Based on what we have covered so far, you can imagine that a module can get quite large. You could also imagine having several independent modules with some common option declarations. It would be ideal if it were possible to split modules apart into component pieces.
That is possible with another top level module attribute, imports
.
Using the same setup from the previous lesson, let us separate the name
, title
, and origin
option declarations into their own modules.
{lib, ...}: {
options = {
name = lib.mkOption {
type = lib.types.str;
};
};
}
{lib, ...}: {
options = {
title = lib.mkOption {
type = lib.types.str;
};
};
}
{lib, ...}: {
options = {
origin = lib.mkOption {
type = lib.types.str;
};
};
}
In our options.nix
file, we import them as using imports
which takes a list of paths.
This is equivalent to if we had declared all of these options in the options.nix
file.
{
lib,
config,
...
}: let
cfg = config;
in {
imports = [
./name.nix
./title.nix
./origin.nix
];
options = {
greeting = lib.mkOption {
type = lib.types.str;
};
};
config = {
greeting = ''
Hello
My name is ${cfg.name}.
I am a ${cfg.title}.
I am from ${cfg.origin}.'';
};
}
Our configuration is the same; we define values for name
, title
, and origin
.
{...}: {
config = {
name = "Boaty McBoatface";
title = "Autonomous Underwater Vehicle";
origin = "England";
};
}
Setup an eval.nix
to evaluate our modules and return the config.greeting
attribute.
{pkgs}:
(
pkgs.lib.evalModules {
modules = [
./options.nix
./config.nix
];
}
)
.config
.greeting
Create a run.sh
run script to evaluate the eval.nix
file.
nix eval -f eval.nix \
--apply 'x: x {pkgs = import <nixpkgs> {};}' \
--json | nix run nixpkgs#jq -- -r
And if we run the script (./run.sh
), we have our configuration.
Hello
My name is Boaty McBoatface.
I am a Autonomous Underwater Vehicle.
I am from England.