Skip to content

Commit

Permalink
lesson/add-lesson-priorities (#34)
Browse files Browse the repository at this point in the history
Added a lesson on option priorities.
  • Loading branch information
djacu authored Mar 8, 2024
1 parent 887dfa4 commit f6bc8c2
Show file tree
Hide file tree
Showing 11 changed files with 146 additions and 0 deletions.
11 changes: 11 additions & 0 deletions lessons/option-priorities/eval-force.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{pkgs}:
(
pkgs.lib.evalModules {
modules = [
./options.nix
./override.nix
./force.nix
];
}
)
.config
10 changes: 10 additions & 0 deletions lessons/option-priorities/eval-override.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{pkgs}:
(
pkgs.lib.evalModules {
modules = [
./options.nix
./override.nix
];
}
)
.config
9 changes: 9 additions & 0 deletions lessons/option-priorities/eval.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{pkgs}:
(
pkgs.lib.evalModules {
modules = [
./options.nix
];
}
)
.config
5 changes: 5 additions & 0 deletions lessons/option-priorities/force.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{lib, ...}: {
config = {
name = lib.mkForce "A Forced Boat";
};
}
84 changes: 84 additions & 0 deletions lessons/option-priorities/lesson.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
# Option priorities

Module options have a *priority*, represented as an integer, which determines the precedence for setting the option to a particular value.
When merging values, the priority with the lowest numeric value will be used.

When evaluating modules, the `default` attribute in `mkOption` uses `mkOptionDefault` internally to assign a priority of 1500.
There are functions that can be used to set an option definitions priority.
`mkDefault`, generally used with option definitions (i.e. `config`), has a priority of 1000.
`mkForce`, generally used when you really *really* want a value to be used, has a priority of 10.
Additionally, option definitions without a priority use `defaultOverridePriority`, which has a priority of 100.

You can use `mkOverride` to create your own option priority.
It takes two arguments: an integer as the priority followed by the option value you want to set.
Like so:

``` nix
config.some-option = mkOverride 42 false;
```

Let us take a look at using these priorities and see how they work.
In our `options.nix` file, we have a declaration and definition for the option `name`.
We are using `mkDefault`, which recall has a priority of 1000, to set the value.

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

Setup an `eval.nix` to evaluate our modules and return the `config` 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)

This is not terribly surprising as we only had a single definition for our option.
There was only a single value that `name` could possibly be.

So what happens if we introduce another definition for `name`.
In `override.nix` we do exactly that.
Here we are setting the value for `name` directly in `config`, which recall will have a priority of 100.
We expect that this should take precedence over our original definition.

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

We have a new `eval-override.nix` to evaluate our modules including the new `override.nix`.

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

A `run-override.sh` run script to evaluate the `eval-override.nix` file.

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

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

[//]: # (self.eval-override)

Great!
Exactly as we expected.
The lower priority value set in `override.nix` took precedence.

Let us do it again.
In `force.nix`, we introduce another definition for `name`, but we use `mkForce`.
Recall that `mkForce` has a priority value of 10.
If we merge this with our other two definitions, we expect that it should take precedence.

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

We have a new `eval-force.nix` to evaluate our modules including the new `force.nix`.

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

A `run-force.sh` run script to evaluate the `eval-force.nix` file.

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

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

[//]: # (self.eval-force)

Great!
Again exactly as expected.
11 changes: 11 additions & 0 deletions lessons/option-priorities/options.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{lib, ...}: {
options = {
name = lib.mkOption {
type = lib.types.str;
};
};

config = {
name = lib.mkDefault "Boaty McBoatface";
};
}
5 changes: 5 additions & 0 deletions lessons/option-priorities/override.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{lib, ...}: {
config = {
name = "A Boat Overridden";
};
}
3 changes: 3 additions & 0 deletions lessons/option-priorities/run-force.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
nix eval -f eval-force.nix \
--apply 'x: x {pkgs = import <nixpkgs> {};}' \
--json | nix run nixpkgs#jq -- -r
3 changes: 3 additions & 0 deletions lessons/option-priorities/run-override.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
nix eval -f eval-override.nix \
--apply 'x: x {pkgs = import <nixpkgs> {};}' \
--json | nix run nixpkgs#jq -- -r
3 changes: 3 additions & 0 deletions lessons/option-priorities/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
2 changes: 2 additions & 0 deletions site/mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ nav:
- lessons/basic-types/lesson.md
- lessons/composed-types/lesson.md
- lessons/submodule-types/lesson.md
- Misc:
- lessons/option-priorities/lesson.md
- Future:
- lessons/default-behavior/lesson.md
- lessons/merging-attrsof/lesson.md
Expand Down

1 comment on commit f6bc8c2

@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.