-
-
Notifications
You must be signed in to change notification settings - Fork 239
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add first lesson for the new module tutorials. (#982)
* Add first lesson for the new module tutorials, and cut redundant parts from the deep dive Co-authored-by: Valentin Gagarin <valentin.gagarin@tweag.io>
- Loading branch information
1 parent
b14ab7b
commit c682c68
Showing
9 changed files
with
159 additions
and
55 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ ... }: | ||
{ | ||
config = { | ||
name = "Boaty McBoatface"; | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
{ pkgs ? import <nixpkgs> { } }: | ||
let | ||
result = pkgs.lib.evalModules { | ||
modules = [ | ||
./options.nix | ||
./config.nix | ||
]; | ||
}; | ||
in | ||
result.config |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
nix-shell -p jq --run "nix-instantiate --eval --json | jq" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
# A basic module | ||
|
||
What is a module? | ||
|
||
* A module is a function that takes an attribute set and returns an attribute set. | ||
* It may declare options, telling which attributes are allowed in the final outcome. | ||
* It may define values, for options declared by itself or other modules. | ||
* When evaluated by the module system, it produces an attribute set based on the declarations and definitions. | ||
|
||
The simplest possible module is a function that takes any attributes and returns an empty attribute set: | ||
|
||
```{code-block} nix | ||
:caption: options.nix | ||
{ ... }: | ||
{ | ||
} | ||
``` | ||
|
||
To define any values, the module system first has to know which ones are allowed. | ||
This is done by declaring *options* that specify which attributes can be set and used elsewhere. | ||
|
||
## Declaring options | ||
|
||
Options are declared under the top-level `options` attribute with [`lib.mkOption`](https://nixos.org/manual/nixpkgs/stable/#function-library-lib.options.mkOption). | ||
|
||
```{literalinclude} options.nix | ||
:language: nix | ||
:caption: options.nix | ||
``` | ||
|
||
:::{note} | ||
The `lib` argument is passed automatically by the module system. | ||
This makes [Nixpkgs library functions](https://nixos.org/manual/nixpkgs/stable/#chap-functions) available in each module's function body. | ||
|
||
The ellipsis `...` is necessary because the module system can pass arbitrary arguments to modules. | ||
|
||
::: | ||
|
||
The attribute `type` in the argument to `lib.mkOption` specifies which values are valid for an option. | ||
There are several types available under [`lib.types`](https://nixos.org/manual/nixos/stable/#sec-option-types-basic). | ||
|
||
Here we have declared an option `name` of type `str`: | ||
The module system will expect a string when a value is defined. | ||
|
||
Now that we have declared an option, we would naturally want to give it a value. | ||
|
||
## Defining values | ||
|
||
Options are set or *defined* under the top-level `config` attribute: | ||
|
||
```{literalinclude} config.nix | ||
:language: nix | ||
:caption: config.nix | ||
``` | ||
|
||
In our option declaration, we created an option `name` with a string type. | ||
Here, in our option definition, we have set that same option to a string. | ||
|
||
Option declarations and option definitions don't need to be in the same file. | ||
Which modules will contribute to the resulting attribute set is specified when setting up module system evaluation. | ||
|
||
## Evaluating modules | ||
|
||
Modules are evaluated by [`lib.evalModules`](https://nixos.org/manual/nixpkgs/stable/#module-system-lib-evalModules) from the Nixpkgs library. | ||
It takes an attribute set as an argument, where the `modules` attribute is a list of modules to merge and evaluate. | ||
|
||
The output of `evalModules` contains information about all evaluated modules, and the final values appear in the attribute `config`. | ||
|
||
```{literalinclude} default.nix | ||
:language: nix | ||
:caption: default.nix | ||
``` | ||
|
||
Here's a helper script to parse and evaluate our `default.nix` file with [`nix-instantiate --eval`](https://nixos.org/manual/nix/stable/command-ref/nix-instantiate) and print the output as JSON: | ||
|
||
```{literalinclude} eval.sh | ||
:language: bash | ||
:caption: eval.sh | ||
``` | ||
|
||
As long as every definition has a corresponding declaration, evaluation will be successful. | ||
If there is an option definition that has not been declared, or the defined value has the wrong type, the module system will throw an error. | ||
|
||
Running the script (`./eval.sh`) should show an output that matches what we have configured: | ||
|
||
```{code-block} | ||
{ | ||
"name": "Boaty McBoatface" | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ lib, ... }: | ||
{ | ||
options = { | ||
name = lib.mkOption { type = lib.types.str; }; | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
# Module system | ||
|
||
Much of the power in Nixpkgs and NixOS comes from the module system. | ||
|
||
The module system is a Nix language library that enables you to | ||
- Declare one attribute set using many separate Nix expressions. | ||
- Impose dynamic type constraints on values in that attribute set. | ||
- Define values for the same attribute in different Nix expressions and merge these values automatically according to their type. | ||
|
||
These Nix expressions are called modules and must have a particular structure. | ||
|
||
In this tutorial series you'll learn | ||
- What a module is and how to create one. | ||
- What options are and how to declare them. | ||
- How to express dependencies between modules. | ||
|
||
## What do you need? | ||
|
||
- Familiarity with data types and general programming concepts | ||
- A {ref}`Nix installation <install-nix>` to run the examples | ||
- Intermediate proficiency in reading and writing the {ref}`Nix language <reading-nix-language>` | ||
|
||
## How long will it take? | ||
|
||
This is a very long tutorial. | ||
Prepare for at least 3 hours of work. | ||
|
||
```{toctree} | ||
:maxdepth: 1 | ||
:caption: Lessons | ||
:numbered: | ||
a-basic-module/index.md | ||
deep-dive.md | ||
``` |