From 57de6a855001eaf849fff1f25859e5a1ddd39ddc Mon Sep 17 00:00:00 2001 From: Maximilian Bosch Date: Wed, 27 Sep 2023 12:45:41 +0200 Subject: nixos/rust-motd: refactor assertion and TOML generation * `sort (<)` also works for strings (TIL!), so no need for comparing length and whether all keys from `cfg.settings` exist in `cfg.order` (slightly less overhead). * Don't build another piece of JSON (`orderedSections`), simply use `cfg.settings`/`cfg.order` with `__structuredAttrs` to ensure a properly ordered TOML. This also has the upside of not having to do quote hackery. * Also, a freeform submodule isn't strictly needed because we don't have any special options defined, so replacing that with `attrsOf format.type`. Co-authored-by: Silvan Mosberger --- nixos/modules/programs/rust-motd.nix | 38 ++++++++++++------------------------ 1 file changed, 13 insertions(+), 25 deletions(-) (limited to 'nixos/modules/programs/rust-motd.nix') diff --git a/nixos/modules/programs/rust-motd.nix b/nixos/modules/programs/rust-motd.nix index e37d72f392f4..4c9b1018596b 100644 --- a/nixos/modules/programs/rust-motd.nix +++ b/nixos/modules/programs/rust-motd.nix @@ -6,31 +6,20 @@ let cfg = config.programs.rust-motd; format = pkgs.formats.toml { }; - orderedSections = listToAttrs - (imap0 - (i: attr: nameValuePair "env${toString i}" { - ${attr} = cfg.settings.${attr}; - }) - cfg.order); - # Order the sections in the TOML according to the order of sections # in `cfg.order`. - # This is done by - # * creating an attribute set with keys `env0`/`env1`/.../`envN` - # where `env0` contains the first section and `envN` the last - # (in the form of `{ sectionName = { /* ... */ }}`) - # * the declarations of `env0` to `envN` in ascending order are - # concatenated with `jq`. Now we have a JSON representation of - # the config in the correct order. - # * this is piped to `json2toml` to get the correct format for rust-motd. motdConf = pkgs.runCommand "motd.conf" - (orderedSections // { + { __structuredAttrs = true; + inherit (cfg) order settings; nativeBuildInputs = [ pkgs.remarshal pkgs.jq ]; - }) + } '' cat "$NIX_ATTRS_JSON_FILE" \ - | jq '${concatMapStringsSep " + " (key: ''."${key}"'') (attrNames orderedSections)}' \ + | jq '.settings as $settings + | .order + | map({ key: ., value: $settings."\(.)" }) + | from_entries' -r \ | json2toml /dev/stdin "$out" ''; in { @@ -60,8 +49,10 @@ in { default = attrNames cfg.settings; defaultText = literalExpression "attrNames cfg.settings"; description = mdDoc '' - The order of the sections in [](#opt-programs.rust-motd.settings) implies - the order of sections in the motd. Since attribute sets in Nix are always + The order of the sections in [](#opt-programs.rust-motd.settings). + By default they are ordered alphabetically. + + Context: since attribute sets in Nix are always ordered alphabetically internally this means that ```nix @@ -89,9 +80,7 @@ in { ''; }; settings = mkOption { - type = types.attrsOf (types.submodule { - freeformType = format.type; - }); + type = types.attrsOf format.type; description = mdDoc '' Settings on what to generate. Please read the [upstream documentation](https://github.com/rust-motd/rust-motd/blob/main/README.md#configuration) @@ -106,8 +95,7 @@ in { `programs.rust-motd` is incompatible with `users.motd`! ''; } - { assertion = length cfg.order == length (attrNames cfg.settings) - && all (section: cfg.settings?${section}) cfg.order; + { assertion = sort (a: b: a < b) cfg.order == attrNames cfg.settings; message = '' Please ensure that every section from `programs.rust-motd.settings` is present in `programs.rust-motd.order`. -- cgit 1.4.1