Merge pull request 'docs(authoring/modules): add examples for dependency injection' (#3249) from hsjobeki/clan-core:docs-authoring into main
Reviewed-on: https://git.clan.lol/clan/clan-core/pulls/3249
This commit is contained in:
@@ -184,3 +184,81 @@ The following example shows how to create a local instance of machine specific s
|
||||
If calling extendSettings is done that doesn't change the original `settings` this means if a different machine tries to access i.e `roles.client.settings` it would *NOT* contain your changes.
|
||||
|
||||
Exposing the changed settings to other machines would come with a huge performance penalty, thats why we don't want to offer it.
|
||||
|
||||
## Passing `self` or `pkgs` to the module
|
||||
|
||||
Passing any dependencies in general must be done manually.
|
||||
|
||||
In general we found the following two best practices:
|
||||
|
||||
1. Using `lib.importApply`
|
||||
2. Using a wrapper module
|
||||
|
||||
Both have pros and cons. After all using `importApply` is the easier one, but might be more limiting sometimes.
|
||||
|
||||
### Using `importApply`
|
||||
|
||||
Using [importApply](https://github.com/NixOS/nixpkgs/pull/230588) is essentially the same as `import file` followed by a function-application; but preserves the error location.
|
||||
|
||||
Imagine your module looks like this
|
||||
|
||||
```nix title="messaging.nix"
|
||||
{ self }:
|
||||
{ ... }: # This line is optional
|
||||
{
|
||||
_class = "clan.service";
|
||||
manifest.name = "messaging"
|
||||
# ...
|
||||
}
|
||||
```
|
||||
|
||||
To import the module use `importApply`
|
||||
|
||||
```nix title=flake.nix
|
||||
# ...
|
||||
outputs = inputs: flake-parts.lib.mkFlake { inherit inputs; } ({self, lib, ...}: {
|
||||
imports = [ inputs.clan-core.flakeModules.default ];
|
||||
# ...
|
||||
clan = {
|
||||
# Register the module
|
||||
inventory.modules."@hsjobeki/messaging" = lib.importApply ./service-modules/messaging.nix { inherit self; };
|
||||
|
||||
# Expose the module for downstream users, 'self' would always point to this flake.
|
||||
modules."@hsjobeki/messaging" = lib.importApply ./service-modules/messaging.nix { inherit self; };
|
||||
};
|
||||
})
|
||||
```
|
||||
|
||||
### Using a wrapper module
|
||||
|
||||
```nix title="messaging.nix"
|
||||
{ config, ... }:
|
||||
{
|
||||
_class = "clan.service";
|
||||
manifest.name = "messaging"
|
||||
# ...
|
||||
# config.myClan
|
||||
}
|
||||
```
|
||||
|
||||
Then wrap the module and forward the variable `self` from the outer context into the module
|
||||
|
||||
```nix title=flake.nix
|
||||
# ...
|
||||
outputs = inputs: flake-parts.lib.mkFlake { inherit inputs; } ({self, lib, ...}: {
|
||||
imports = [ inputs.clan-core.flakeModules.default ];
|
||||
# ...
|
||||
clan = {
|
||||
# Register the module
|
||||
inventory.modules."@hsjobeki/messaging" = {
|
||||
# Create an option 'myClan' and assign it to 'self'
|
||||
options.myClan = lib.mkOption {
|
||||
default = self;
|
||||
};
|
||||
imports = [./service-modules/messaging.nix ];
|
||||
}
|
||||
};
|
||||
})
|
||||
```
|
||||
|
||||
The benefit of this approach is that downstream users can override the value of `myClan` by using `mkForce` or other priority modifiers.
|
||||
|
||||
Reference in New Issue
Block a user