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/add-submodule-types #32

Merged
merged 1 commit into from
Mar 6, 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
40 changes: 40 additions & 0 deletions lessons/submodule-types/character.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{
lib,
options,
config,
...
}: let
cfg = config;
opts = options;
in {
options = {
name = lib.mkOption {
type = lib.types.str;
};
title = lib.mkOption {
type = lib.types.str;
};
origin = lib.mkOption {
type = lib.types.str;
};

greeting = lib.mkOption {
type = lib.types.str;
};
};

config = {
greeting = (
lib.concatStringsSep
"\n"
(
[
"Hello"
]
++ (lib.optional opts.name.isDefined "My name is ${cfg.name}.")
++ (lib.optional opts.title.isDefined "I am a ${cfg.title}.")
++ (lib.optional opts.origin.isDefined "I am from ${cfg.origin}.")
)
);
};
}
15 changes: 15 additions & 0 deletions lessons/submodule-types/config.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{...}: {
config = {
characters = [
{
name = "Boaty McBoatface";
origin = "England";
}
{
name = "djacu";
title = "Nix Enthusiast";
origin = "USA";
}
];
};
}
11 changes: 11 additions & 0 deletions lessons/submodule-types/eval.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{pkgs}:
(
pkgs.lib.evalModules {
modules = [
./options.nix
./config.nix
];
}
)
.config
.greeting
40 changes: 40 additions & 0 deletions lessons/submodule-types/lesson.md
Original file line number Diff line number Diff line change
@@ -1 +1,41 @@
# Submodule Types

After learning about composed types, you can imagine that nesting can get deep quickly.
The logic for tracking each layer can become overwhelming.
This is where one of the most useful types included in type system comes into play: `submodule`.
It allows you to define nested modules with their own option imports, declarations, and definitions.

First we will define our submodule.
In `character.nix` we have something that looks very similar to what we built before.
We have `name`, `title`, and `origin` as inputs and a greeting that combines all these as an output.

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

In our `options.nix`, we have a `characters` option that is a list of submodule that points to our `character.nix` file.
We have also defined a `greeting` option that will take all `greeting` definitions from our characters and join them into a single string.
Note: these two `greeting` options are not the same; `character.nix` and `options.nix` each have their own `greeting` option.

!!! note
We could have written the `character.nix` submodule in place.
For the sake of readability, we gave it its own file.
Also, writing it in its own file allows us to use it elsewhere if desired.

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

In our `config.nix`, we define all of our characters.
The behavior of the submodule type is attr-*like*.
So inside our list we have attribute sets; each one can have a value for attributes `name`, `title` and `origin`.

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

Setup an `eval.nix` to evaluate our modules and return the `config.greeting` attribute.

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

Create a `run.sh` run script to evaluate the `eval.nix` file.

[//]: # (./run.sh)

And if we run the script (`./run.sh`), we have our configuration.

[//]: # (self.eval)
27 changes: 27 additions & 0 deletions lessons/submodule-types/options.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
lib,
config,
...
}: let
cfg = config;
in {
options = {
characters = lib.mkOption {
type = lib.types.listOf (lib.types.submodule ./character.nix);
};
greeting = lib.mkOption {
type = lib.types.str;
};
};

config = {
greeting =
lib.concatStringsSep
"\n\n"
(
builtins.map
(character: character.greeting)
cfg.characters
);
};
}
3 changes: 3 additions & 0 deletions lessons/submodule-types/run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
nix eval -f eval.nix \
--apply 'x: x {pkgs = import <nixpkgs> {};}' \
--json | nix run nixpkgs#jq -- -r
Loading