Skip to content

Commit

Permalink
lesson/add-submodule-types (#32)
Browse files Browse the repository at this point in the history
Added content for the submodule lesson.
  • Loading branch information
djacu authored Mar 6, 2024
1 parent 996d0b2 commit a358a3e
Show file tree
Hide file tree
Showing 6 changed files with 136 additions and 0 deletions.
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

1 comment on commit a358a3e

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.