Skip to content

Module Evaluation

Let us look at a basic, trivial example. We will use the options.nix and config.nix from the previous lesson.

In the options.nix file, we have a single option, name, that is of type str.

options.nix
{lib, ...}: {
  options = {
    name = lib.mkOption {
      type = lib.types.str;
    };
  };
}

In the config.nix file, we have defined a value for name.

config.nix
{
  config.name = "Boaty McBoatface";
}

What do we do now?

How do we combine these two modules together?

With a simple function, evalModules.

pkgs.lib.evalModules {
  modules = [
    ./options.nix
    ./config.nix
  ];
}

That is it. Provide the modules you want to evaluate in a list to the modules attribute. evalModules will take take all the modules provided and intelligently merge them together.

If we were to run that, we would get a big messy output. The result is a big attrset with several attributes. For now, the attribute we care about is config.

In the eval.nix file, we take the code from above and get the config attribute from the evaluation.

eval.nix
{pkgs}:
(
  pkgs.lib.evalModules {
    modules = [
      ./options.nix
      ./config.nix
    ];
  }
)
.config

In the run.sh file, we evaluate the eval.nix file and have it print out a nicely formatted version of the configuration.

run.sh
nix eval -f eval.nix \
    --apply 'x: x {pkgs = import <nixpkgs> {};}' \
    --json | nix run nixpkgs#jq -- .

If you execute the run file (./run.sh), you should see an output that matches what we have configured.

{
  "name": "Boaty McBoatface"
}