Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lesson/improve module evaluation #19

Merged
merged 1 commit into from
Feb 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions lessons/module-evaluation/config.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
config.name = "Boaty McBoatface";
}
26 changes: 9 additions & 17 deletions lessons/module-evaluation/eval.nix
Original file line number Diff line number Diff line change
@@ -1,18 +1,10 @@
{pkgs}: let
mymodule = {
imports = [
{pkgs}:
(
pkgs.lib.evalModules {
modules = [
./options.nix
./config.nix
];
options = {
};
config = {
};
};
in
(
pkgs.lib.evalModules {
modules = [
mymodule
];
}
)
.config
}
)
.config
54 changes: 32 additions & 22 deletions lessons/module-evaluation/lesson.md
Original file line number Diff line number Diff line change
@@ -1,38 +1,48 @@
# Module Evaluation

In the [eval][eval] file, we have declared an attrset called `mymodule` which is composed of 3
fields: `imports`, `options` and `config`. This is a module with default values for those fields.
You can omit any of those fields and they will use those same default values.
Let us look at a basic, trivial example.
We will use the `options.nix` and `config.nix` from the previous lesson.

[//]: # (./eval.nix)
In the `options.nix` file, we have a single option, `name`, that is of type `str`.

[//]: # (./options.nix)

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

If you execute the run file (`./run`), you will see printed the empty JSON object `{}`.
[//]: # (./config.nix)

[eval]: ./eval.nix
What do we do now?

## Module Fields
How do we combine these two modules together?

The `options` field lets you define variables that can be used in the `config` section.
With a simple function, `evalModules`.

The `config` field assigns values to options defined in other modules. We call this using an option.
``` nix
pkgs.lib.evalModules {
modules = [
./options.nix
./config.nix
];
}
```

The `imports` field lets you import other modules from a module.
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.

We will see what goes in those fields in later lessons.
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`.

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

[//]: # (./eval.nix)

In the [eval][eval] file, we use a function called `evalModules`. This function takes an attrset as
argument which can contain the field named `modules`. In there, we can put as many module as we
want.
In the `run.sh` file, we evaluate the `eval.nix` file and have it print out a nicely formatted version of the configuration.

`evalModules` will then merge all `imports`, `options` and `config` fields of all given modules
following some rules we will see in the next lessons. It then produces an attrset whose only
interesting field - the result of merging all modules - is found in the `config` field. This is the
one we print when executing the `./run` file.
[//]: # (./run.sh)

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

The vast majority of nixpkgs is made out of modules, all merged together in the top-level
`evalModules`.
[//]: # (self.eval)

7 changes: 7 additions & 0 deletions lessons/module-evaluation/options.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{lib, ...}: {
options = {
name = lib.mkOption {
type = lib.types.str;
};
};
}
1 change: 0 additions & 1 deletion lessons/module-evaluation/run

This file was deleted.

1 change: 1 addition & 0 deletions lessons/module-evaluation/run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
nix eval -f eval.nix --apply 'x: x {pkgs = import <nixpkgs> {};}' --json | nix run nixpkgs#jq -- .
Loading