-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
post: self implementing module systems
- Loading branch information
Showing
1 changed file
with
49 additions
and
0 deletions.
There are no files selected for viewing
49 changes: 49 additions & 0 deletions
49
content/posts/2024-03-30-self-implementing-module-systems.md
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,49 @@ | ||
--- | ||
title: "Nix module trick: Re-evaluating yourself" | ||
date: 2024-03-30 | ||
draft: false | ||
markup: "mmark" | ||
--- | ||
|
||
This is a cool trick for those playing around with Nix's module | ||
system. While developing | ||
[nix-config-modules](https://github.com/chadac/nix-config-modules/), I | ||
ran into a semi-unique issue: In the module system I defined a set of | ||
*hosts* and a separate, general set of *apps*, and hosts could define | ||
which *apps* they could import. | ||
|
||
To generate this subset of `app` configurations, I wanted to be able | ||
to re-evaluate all of my `app` modules with a host argument. In other | ||
words, I wanted to be able to write modules like: | ||
|
||
```nix | ||
{ host, ... }: | ||
{ | ||
app.emacs = { | ||
enable = host.kind == "nixos"; | ||
}; | ||
} | ||
``` | ||
|
||
And then essentially I would call `lib.evalModules` on the apps | ||
modules with the `host` argument substituted with each host I had | ||
configured. | ||
|
||
What I needed was, in my module system I needed to grab all the | ||
modules that defined my modules. Fortunately Nix makes this easy: | ||
every module gets a `moduleType` argument that includes the definition | ||
of all modules. So if you need to reevaluate all of your modules with | ||
a special additional configuration, all you need to do is: | ||
|
||
```nix | ||
{ lib, moduleType, ... }: | ||
# < ... > | ||
lib.evalModules { | ||
modules = moduleType.getSubModules ++ [ | ||
{ _module.args.host = myHost; } | ||
]; | ||
}; | ||
``` | ||
|
||
Of course you'd need to be extremely careful as there's a huge risk of | ||
infinite recursion here, but it can be pretty handy. |