Unverified Commit 4305d167 authored by Maximilian Bosch's avatar Maximilian Bosch Committed by GitHub
Browse files

Merge pull request #256407 from Ma27/motd-ordering

nixos/rust-motd: allow ordering sections
parents 6e8e41ec 57de6a85
Loading
Loading
Loading
Loading
+61 −4
Original line number Diff line number Diff line
@@ -5,6 +5,23 @@ with lib;
let
  cfg = config.programs.rust-motd;
  format = pkgs.formats.toml { };

  # Order the sections in the TOML according to the order of sections
  # in `cfg.order`.
  motdConf = pkgs.runCommand "motd.conf"
    {
      __structuredAttrs = true;
      inherit (cfg) order settings;
      nativeBuildInputs = [ pkgs.remarshal pkgs.jq ];
    }
    ''
      cat "$NIX_ATTRS_JSON_FILE" \
        | jq '.settings as $settings
              | .order
              | map({ key: ., value: $settings."\(.)" })
              | from_entries' -r \
        | json2toml /dev/stdin "$out"
    '';
in {
  options.programs.rust-motd = {
    enable = mkEnableOption (lib.mdDoc "rust-motd");
@@ -27,10 +44,43 @@ in {
        For possible formats, please refer to {manpage}`systemd.time(7)`.
      '';
    };
    settings = mkOption {
      type = types.submodule {
        freeformType = format.type;
    order = mkOption {
      type = types.listOf types.str;
      default = attrNames cfg.settings;
      defaultText = literalExpression "attrNames cfg.settings";
      description = mdDoc ''
        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
        {
          uptime = { /* ... */ };
          banner = { /* ... */ };
        }
        ```

        will still have `banner` displayed before `uptime`.

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

        ```nix
        {
          order = [
            "uptime"
            "banner"
          ];
        }
        ```

        makes sure that `uptime` is placed before `banner` in the motd.
      '';
    };
    settings = mkOption {
      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)
@@ -45,14 +95,21 @@ in {
          `programs.rust-motd` is incompatible with `users.motd`!
        '';
      }
      { 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`.
        '';
      }
    ];
    systemd.services.rust-motd = {
      path = with pkgs; [ bash ];
      documentation = [ "https://github.com/rust-motd/rust-motd/blob/v${pkgs.rust-motd.version}/README.md" ];
      description = "motd generator";
      wantedBy = [ "multi-user.target" ];
      serviceConfig = {
        ExecStart = "${pkgs.writeShellScript "update-motd" ''
          ${pkgs.rust-motd}/bin/rust-motd ${format.generate "motd.conf" cfg.settings} > motd
          ${pkgs.rust-motd}/bin/rust-motd ${motdConf} > motd
        ''}";
        CapabilityBoundingSet = [ "" ];
        LockPersonality = true;