fnott: add module

Fnott is a keyboard driven and lightweight Wayland notification daemon
for wlroots-based compositors.

There are four unit test to validate behavior for an empty
configuration, the default configuration, global properties and
systemd service file generation.
This commit is contained in:
polykernel 2021-08-10 00:21:03 -04:00 committed by Robert Helgesson
parent 84d54402a5
commit 521a03d8bf
No known key found for this signature in database
GPG key ID: 36BDAA14C2797E89
13 changed files with 250 additions and 0 deletions

3
.github/CODEOWNERS vendored
View file

@ -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

View file

@ -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'.
'';
}
];
};
}

View file

@ -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

130
modules/services/fnott.nix Normal file
View file

@ -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 <command>fnott</command>.";
};
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.
</para><para>
Note that environment variables in the path won't be properly expanded.
</para><para>
The configuration specified under
<option>services.fnott.settings</option> will be generated and
written to <filename>$XDG_CONFIG_HOME/fnott/fnott.ini</filename>
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
<filename>$XDG_CONFIG_HOME/fnott/fnott.ini</filename>.
</para><para>
See
<citerefentry>
<refentrytitle>fnott.ini</refentrytitle>
<manvolnum>5</manvolnum>
</citerefentry> for a list of avaliable options and <link
xlink:href="https://codeberg.org/dnkl/fnott/src/branch/master/fnott.ini"/>
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" ]))
]);
})
]);
};
}

View file

@ -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

View file

@ -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;
}

View file

@ -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
'';
};
}

View file

@ -0,0 +1,6 @@
notification-margin=5
[low]
timeout=5
title-color=ffffff
title-font=Dina:weight=bold:slant=italic

View file

@ -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}
'';
};
}

View file

@ -0,0 +1,2 @@
max-icon-size=32
notification-margin=5

View file

@ -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}
'';
};
}

View file

@ -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

View file

@ -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}
'';
};
}