diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 2d46797c5..2720c7eb2 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -238,6 +238,9 @@ /modules/services/fluidsynth.nix @Valodim +/modules/services/fnott.nix @polykernel +/tests/modules/services/fnott @polykernel + /modules/services/git-sync.nix @IvanMalison /modules/services/gnome-keyring.nix @rycee diff --git a/modules/misc/news.nix b/modules/misc/news.nix index 183db4472..69a187698 100644 --- a/modules/misc/news.nix +++ b/modules/misc/news.nix @@ -2180,6 +2180,14 @@ in A new module is available: 'services.git-sync'. ''; } + + { + time = "2021-08-26T06:40:59+00:00"; + condition = hostPlatform.isLinux; + message = '' + A new module is available: 'services.fnott'. + ''; + } ]; }; } diff --git a/modules/modules.nix b/modules/modules.nix index ad311ac85..db6bdb295 100644 --- a/modules/modules.nix +++ b/modules/modules.nix @@ -162,6 +162,7 @@ let ./services/etesync-dav.nix ./services/flameshot.nix ./services/fluidsynth.nix + ./services/fnott.nix ./services/getmail.nix ./services/git-sync.nix ./services/gnome-keyring.nix diff --git a/modules/services/fnott.nix b/modules/services/fnott.nix new file mode 100644 index 000000000..a6a1aa690 --- /dev/null +++ b/modules/services/fnott.nix @@ -0,0 +1,130 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let + cfg = config.services.fnott; + + concatStringsSep' = sep: list: + concatStringsSep sep (filter (str: str != "") list); + + mkKeyValue = generators.mkKeyValueDefault { } "="; + genINI = generators.toINI { }; + + iniFormatType = with types; + let + iniAtom = types.nullOr (types.oneOf [ bool int float str ]) // { + description = "INI atom (null, bool, int, float or string)"; + }; + in attrsOf (attrsOf iniAtom); +in { + options = { + services.fnott = { + enable = mkEnableOption '' + fnott, a lightweight Wayland notification daemon for wlroots-based compositors + ''; + + package = mkOption { + type = types.package; + default = pkgs.fnott; + defaultText = literalExample "pkgs.fnott"; + description = "Package providing fnott."; + }; + + configFile = mkOption { + type = types.either types.str types.path; + default = "${config.xdg.configHome}/fnott/fnott.ini"; + defaultText = "$XDG_CONFIG_HOME/fnott/fnott.ini"; + description = '' + Path to the configuration file read by fnott. + + Note that environment variables in the path won't be properly expanded. + + The configuration specified under + will be generated and + written to $XDG_CONFIG_HOME/fnott/fnott.ini + regardless of this option. This allows using a mutable configuration file + generated from the immutable one, useful in scenarios where live reloading is desired. + ''; + }; + + extraFlags = mkOption { + type = types.listOf types.str; + default = [ ]; + example = [ "-s" ]; + description = '' + Extra arguments to use for executing fnott. + ''; + }; + + settings = mkOption { + type = iniFormatType; + default = { }; + description = '' + Configuration written to + $XDG_CONFIG_HOME/fnott/fnott.ini. + + See + + fnott.ini + 5 + for a list of avaliable options and + for an example configuration. + ''; + example = literalExample '' + { + main = { + notification-margin = 5; + }; + + low = { + timeout = 5; + title-font = "Dina:weight=bold:slant=italic"; + title-color = "ffffff"; + }; + } + ''; + }; + }; + }; + + config = mkIf cfg.enable { + assertions = + [ (hm.assertions.assertPlatform "services.fnott" pkgs platforms.linux) ]; + + home.packages = [ cfg.package ]; + + systemd.user.services.fnott = { + Unit = { + Description = "Fnott notification daemon"; + Documentation = "man:fnott(1)"; + After = [ "graphical-session-pre.target" ]; + PartOf = [ "graphical-session.target" ]; + }; + + Service = { + Type = "dbus"; + BusName = "org.freedesktop.Notifications"; + ExecStart = concatStringsSep' " " [ + "${cfg.package}/bin/fnott -c ${cfg.configFile}" + (escapeShellArgs cfg.extraFlags) + ]; + }; + }; + + # FIXME: Remove after next version release (https://codeberg.org/dnkl/fnott/pulls/24). + xdg.configFile."fnott/fnott.ini" = mkIf (cfg.settings != { }) (mkMerge [ + { text = genINI cfg.settings; } + (mkIf (cfg.settings ? main) { + text = mkForce (concatStringsSep' "\n" [ + '' + ${concatStringsSep "\n" + (mapAttrsToList mkKeyValue cfg.settings.main)} + '' + (genINI (removeAttrs cfg.settings [ "main" ])) + ]); + }) + ]); + }; +} diff --git a/tests/default.nix b/tests/default.nix index b2b6be6bf..161b4897a 100644 --- a/tests/default.nix +++ b/tests/default.nix @@ -120,6 +120,7 @@ import nmt { ./modules/services/dropbox ./modules/services/emacs ./modules/services/fluidsynth + ./modules/services/fnott ./modules/services/git-sync ./modules/services/kanshi ./modules/services/lieer diff --git a/tests/modules/services/fnott/default.nix b/tests/modules/services/fnott/default.nix new file mode 100644 index 000000000..4ce849ff5 --- /dev/null +++ b/tests/modules/services/fnott/default.nix @@ -0,0 +1,6 @@ +{ + fnott-empty-settings = ./empty-settings.nix; + fnott-example-settings = ./example-settings.nix; + fnott-global-properties = ./global-properties.nix; + fnott-systemd-user-service = ./systemd-user-service.nix; +} diff --git a/tests/modules/services/fnott/empty-settings.nix b/tests/modules/services/fnott/empty-settings.nix new file mode 100644 index 000000000..85d2c9d6a --- /dev/null +++ b/tests/modules/services/fnott/empty-settings.nix @@ -0,0 +1,15 @@ +{ config, lib, pkgs, ... }: + +{ + config = { + services.fnott = { + enable = true; + package = pkgs.writeScriptBin "dummy-fnott" ""; + settings = { }; + }; + + nmt.script = '' + assertPathNotExists home-files/.config/fnott + ''; + }; +} diff --git a/tests/modules/services/fnott/example-settings-expected.ini b/tests/modules/services/fnott/example-settings-expected.ini new file mode 100644 index 000000000..153e456ca --- /dev/null +++ b/tests/modules/services/fnott/example-settings-expected.ini @@ -0,0 +1,6 @@ +notification-margin=5 + +[low] +timeout=5 +title-color=ffffff +title-font=Dina:weight=bold:slant=italic diff --git a/tests/modules/services/fnott/example-settings.nix b/tests/modules/services/fnott/example-settings.nix new file mode 100644 index 000000000..3685637d7 --- /dev/null +++ b/tests/modules/services/fnott/example-settings.nix @@ -0,0 +1,26 @@ +{ config, lib, pkgs, ... }: + +{ + config = { + services.fnott = { + enable = true; + package = pkgs.writeScriptBin "dummy-fnott" ""; + + settings = { + main = { notification-margin = 5; }; + + low = { + timeout = 5; + title-font = "Dina:weight=bold:slant=italic"; + title-color = "ffffff"; + }; + }; + }; + + nmt.script = '' + assertFileContent \ + home-files/.config/fnott/fnott.ini \ + ${./example-settings-expected.ini} + ''; + }; +} diff --git a/tests/modules/services/fnott/global-properties-expected.ini b/tests/modules/services/fnott/global-properties-expected.ini new file mode 100644 index 000000000..a82646797 --- /dev/null +++ b/tests/modules/services/fnott/global-properties-expected.ini @@ -0,0 +1,2 @@ +max-icon-size=32 +notification-margin=5 diff --git a/tests/modules/services/fnott/global-properties.nix b/tests/modules/services/fnott/global-properties.nix new file mode 100644 index 000000000..5a9d7e038 --- /dev/null +++ b/tests/modules/services/fnott/global-properties.nix @@ -0,0 +1,24 @@ +{ config, lib, pkgs, ... }: + +# FIXME: Deprecate on next version release of fnott (https://codeberg.org/dnkl/fnott/pulls/24). +{ + config = { + services.fnott = { + enable = true; + package = pkgs.writeScriptBin "dummy-fnott" ""; + + settings = { + main = { + max-icon-size = 32; + notification-margin = 5; + }; + }; + }; + + nmt.script = '' + assertFileContent \ + home-files/.config/fnott/fnott.ini \ + ${./global-properties-expected.ini} + ''; + }; +} diff --git a/tests/modules/services/fnott/systemd-user-service-expected.service b/tests/modules/services/fnott/systemd-user-service-expected.service new file mode 100644 index 000000000..c39a7b19b --- /dev/null +++ b/tests/modules/services/fnott/systemd-user-service-expected.service @@ -0,0 +1,10 @@ +[Service] +BusName=org.freedesktop.Notifications +ExecStart=@fnott@/bin/fnott -c /home/hm-user/.config/fnott/fnott.ini +Type=dbus + +[Unit] +After=graphical-session-pre.target +Description=Fnott notification daemon +Documentation=man:fnott(1) +PartOf=graphical-session.target diff --git a/tests/modules/services/fnott/systemd-user-service.nix b/tests/modules/services/fnott/systemd-user-service.nix new file mode 100644 index 000000000..a356f2ae9 --- /dev/null +++ b/tests/modules/services/fnott/systemd-user-service.nix @@ -0,0 +1,18 @@ +{ config, lib, pkgs, ... }: + +{ + config = { + services.fnott = { + enable = true; + package = pkgs.writeScriptBin "dummy-foot" "" // { outPath = "@fnott@"; }; + }; + + nmt.script = '' + assertPathNotExists home-files/.config/fnott/fnott.ini + + assertFileContent \ + home-files/.config/systemd/user/fnott.service \ + ${./systemd-user-service-expected.service} + ''; + }; +}