Unverified Commit d77b59b4 authored by Maximilian Bosch's avatar Maximilian Bosch
Browse files

nixos/rust-motd: use a second attribute (`order`) for the of sections in TOML

Rather than using `priority` with `sortProperties`, a new option called
`order` defines the ordering of the sections. I.e.

    order = [ "global" "uptime" "banner" ]

means that `uptime` comes before `banner`. Please note that `global` is
for global settings and not a section. I figured that it'd be too much
magic to hide this in the implementation and ask the user to specify the
order of _each_ section in `settings` instead.

OTOH this makes the intent way clearer than priorities. Also, this
remains opt-in, the option defaults to `attrNames cfg.settings`, i.e.
all sections ordered alphabetically.
parent 214cf0b9
Loading
Loading
Loading
Loading
+44 −29
Original line number Diff line number Diff line
@@ -8,12 +8,13 @@ let

  orderedSections = listToAttrs
    (imap0
      (i: items@{ sectionHeader, ... }: nameValuePair "env${toString i}" {
        ${sectionHeader} = removeAttrs items [ "priority" "sectionHeader" ];
      (i: attr: nameValuePair "env${toString i}" {
        ${attr} = cfg.settings.${attr};
      })
      (sortProperties (mapAttrsToList (k: v: v // { sectionHeader = k; }) cfg.settings)));
      cfg.order);

  # Order the sections in the TOML according to the `priority` field.
  # 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
@@ -54,35 +55,42 @@ in {
        For possible formats, please refer to {manpage}`systemd.time(7)`.
      '';
    };
    settings = mkOption {
      type = types.attrsOf (types.submodule {
        freeformType = format.type;
        options.priority = mkOption {
          type = types.int;
          default = modules.defaultOrderPriority;
    order = mkOption {
      type = types.listOf types.str;
      default = attrNames cfg.settings;
      defaultText = literalExpression "attrNames cfg.settings";
      description = mdDoc ''
            In `rust-motd`, the order of the sections in TOML correlates to the order
            of the items displayed in the resulting `motd`. Attributes in Nix are
            ordered alphabetically, e.g. `banner` would always be before `uptime`.
        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
        ordered alphabetically internally this means that

        ```nix
        {
          uptime = { /* ... */ };
          banner = { /* ... */ };
        }
        ```

            To change that, this option can be used. The lower this number is, the higher
            is the priority and the more a section is at the top of the message.
        will still have `banner` displayed before `uptime`.

            For instance
        To work around that, this option can be used to define the order of all keys,
        i.e.

        ```nix
        {
              banner.command = "hostname | figlet -f slant";
              uptime = {
                prefix = "Up";
                priority = 0;
              };
          order = [
            "uptime"
            "banner"
          ];
        }
        ```

            would make the `uptime` appear before the banner.
        makes sure that `uptime` is placed before `banner` in the motd.
      '';
    };
    settings = mkOption {
      type = types.attrsOf (types.submodule {
        freeformType = format.type;
      });
      description = mdDoc ''
        Settings on what to generate. Please read the
@@ -98,6 +106,13 @@ in {
          `programs.rust-motd` is incompatible with `users.motd`!
        '';
      }
      { assertion = length cfg.order == length (attrNames cfg.settings)
          && all (section: cfg.settings?${section}) cfg.order;
        message = ''
          Please ensure that every section from `programs.rust-motd.settings` is present in
          `programs.rust-motd.order`.
        '';
      }
    ];
    systemd.services.rust-motd = {
      path = with pkgs; [ bash ];