1
Fork 0
mirror of https://github.com/RGBCube/hjem synced 2025-10-13 13:12:16 +00:00

modules: add users.<user>.files.<name>.{generator,value} options

This commit is contained in:
Seth Flynn 2025-05-10 22:27:44 -04:00 committed by éclairevoyant
parent f0f5dbda76
commit 386d56af28
No known key found for this signature in database
GPG key ID: E3813AEAA02DB54B
3 changed files with 65 additions and 12 deletions

View file

@ -49,6 +49,15 @@ may use to manage individual users' homes by leveraging the module system.
# This can be used to generate config files with various
# formats expected by different programs.
".config/bar".source = pkgs.writeTextFile "file-foo" "file contents";
# You can also use generators to transform Nix values
".config/baz" = {
# Works with `pkgs.formats` too!
generator = lib.generators.toJSON { };
value = {
some = "contents";
};
};
};
};
}

View file

@ -10,10 +10,10 @@
}: let
inherit (lib.attrsets) mapAttrsToList;
inherit (lib.strings) concatMapStringsSep concatLines;
inherit (lib.modules) mkIf mkDefault mkDerivedConfig;
inherit (lib.modules) mkIf mkDefault mkDerivedConfig mkMerge;
inherit (lib.options) mkOption literalExpression mkEnableOption;
inherit (lib.strings) hasPrefix;
inherit (lib.types) attrsOf bool lines listOf nullOr package path str submodule oneOf int;
inherit (lib.types) anything attrsOf bool either functionTo lines listOf nullOr package path str submodule oneOf int;
inherit (builtins) isList;
cfg = config;
@ -58,6 +58,22 @@
description = "Path of the source file or directory";
};
generator = lib.mkOption {
type = nullOr (functionTo (either options.source.type options.text.type));
default = null;
description = "Function that when applied to `value` will create the `text` of the file.";
example = literalExpression "lib.generators.toGitINI";
};
value = lib.mkOption {
type = nullOr (attrsOf anything);
default = null;
description = "Value passed to the `generator`.";
example = {
user.email = "me@example.com";
};
};
executable = mkOption {
type = bool;
default = false;
@ -90,14 +106,27 @@
};
};
config = {
target = mkDefault name;
source = mkIf (config.text != null) (mkDerivedConfig options.text (text:
pkgs.writeTextFile {
inherit name text;
inherit (config) executable;
}));
};
config = let
generatedValue = config.generator config.value;
in
mkMerge [
{
target = mkDefault name;
source = mkIf (config.text != null) (mkDerivedConfig options.text (text:
pkgs.writeTextFile {
inherit name text;
inherit (config) executable;
}));
}
(lib.mkIf (config.generator != null && options.source.type.check generatedValue) {
source = mkDefault generatedValue;
})
(lib.mkIf (config.generator != null && options.text.type.check generatedValue) {
text = mkDefault generatedValue;
})
];
});
in {
imports = [

View file

@ -6,6 +6,7 @@ in
nodes = {
node1 = {
self,
lib,
pkgs,
...
}: {
@ -22,8 +23,20 @@ in
alice = {
enable = true;
packages = [pkgs.hello];
files.".config/foo" = {
text = "Hello world!";
files = {
".config/foo" = {
text = "Hello world!";
};
".config/bar.json" = {
generator = lib.generators.toJSON {};
value = {bar = true;};
};
".config/baz.toml" = {
generator = (pkgs.formats.toml {}).generate "baz.toml";
value = {baz = true;};
};
};
};
};
@ -47,6 +60,8 @@ in
# Test file created by Hjem
machine.succeed("[ -L ~alice/.config/foo ]")
machine.succeed("[ -L ~alice/.config/bar.json ]")
machine.succeed("[ -L ~alice/.config/baz.toml ]")
# Test regular files, created by systemd-tmpfiles
machine.succeed("[ -d ~alice/user_tmpfiles_created ]")