recoll: add module

This commit is contained in:
Gabriel Arazas 2022-02-07 18:54:09 +08:00 committed by Robert Helgesson
parent b13946438f
commit 0e2f7876d2
No known key found for this signature in database
GPG key ID: 36BDAA14C2797E89
10 changed files with 330 additions and 0 deletions

3
.github/CODEOWNERS vendored
View file

@ -413,6 +413,9 @@ Makefile @thiagokokada
/modules/services/random-background.nix @rycee
/modules/services/recoll.nix @foo-dogsquared
/tests/modules/recoll @foo-dogsquared
/modules/services/redshift-gammastep @rycee @petabyteboy @thiagokokada
/tests/modules/redshift-gammastep @thiagokokada

View file

@ -624,6 +624,14 @@ in
A new module is available: 'xsession.windowManager.spectrwm'.
'';
}
{
time = "2022-07-27T12:22:37+00:00";
condition = hostPlatform.isLinux;
message = ''
A new module is available: 'services.recoll'.
'';
}
];
};
}

View file

@ -242,6 +242,7 @@ let
./services/poweralertd.nix
./services/pulseeffects.nix
./services/random-background.nix
./services/recoll.nix
./services/redshift-gammastep/gammastep.nix
./services/redshift-gammastep/redshift.nix
./services/rsibreak.nix

192
modules/services/recoll.nix Normal file
View file

@ -0,0 +1,192 @@
{ config, options, lib, pkgs, ... }:
with lib;
# TODO: Fix the formatting of the resulting config.
let
cfg = config.services.recoll;
# The key-value generator for Recoll config format. For future references,
# see the example configuration from the package (i.e.,
# `$out/share/recoll/examples/recoll.conf`).
mkRecollConfKeyValue = generators.mkKeyValueDefault {
mkValueString = v:
if v == true then
"1"
else if v == false then
"0"
else if isList v then
concatStringsSep " " v
else
generators.mkValueStringDefault { } v;
} " = ";
# A modified version of 'lib.generators.toINI' that also accepts top-level
# attributes as non-attrsets.
toRecollConf = { listsAsDuplicateKeys ? false }:
attr:
let
toKeyValue = generators.toKeyValue {
inherit listsAsDuplicateKeys;
mkKeyValue = mkRecollConfKeyValue;
};
mkSectionName = name: strings.escape [ "[" "]" ] name;
convert = k: v:
if isAttrs v then
''
[${mkSectionName k}]
'' + toKeyValue v
else
toKeyValue { "${k}" = v; };
# TODO: Improve this chunk of code, pls.
# There's a possibility of attributes with attrsets overriding other
# top-level attributes with non-attrsets so we're forcing the attrsets to
# come last.
_config = mapAttrsToList convert (filterAttrs (k: v: !isAttrs v) attr);
_config' = mapAttrsToList convert (filterAttrs (k: v: isAttrs v) attr);
config = _config ++ _config';
in concatStringsSep "\n" config;
# A specific type for Recoll config format. Taken from `pkgs.formats`
# implementation from nixpkgs. See the 'Nix-representable formats' from the
# NixOS manual for more information.
recollConfFormat = { }: {
type = with types;
let
valueType = nullOr (oneOf [
bool
float
int
path
str
(attrsOf valueType)
(listOf valueType)
]) // {
description = "Recoll config value";
};
in attrsOf valueType;
generate = name: value: pkgs.writeText name (toRecollConf { } value);
};
# The actual object we're going to use for this module. This is for the sake
# of consistency (and dogfooding the settings format implementation).
settingsFormat = recollConfFormat { };
in {
meta.maintainers = [ maintainers.foo-dogsquared ];
options.services.recoll = {
enable = mkEnableOption "Recoll file index service";
package = mkOption {
type = types.package;
default = pkgs.recoll;
defaultText = literalExpression "pkgs.recoll";
description = ''
Package providing the <literal>recoll</literal> binary.
'';
example = literalExpression "(pkgs.recoll.override { withGui = false; })";
};
startAt = mkOption {
type = types.str;
default = "hourly";
example = "00/2:00";
description = ''
When or how often the periodic update should run. Must be the format
described from
<citerefentry>
<refentrytitle>systemd.time</refentrytitle>
<manvolnum>7</manvolnum>
</citerefentry>.
'';
};
settings = mkOption {
type = settingsFormat.type;
default = { };
description = ''
The configuration to be written at
<filename>''${config.services.recoll.configDir}/recoll.conf</filename>.
See
<citerefentry>
<refentrytitle>recoll</refentrytitle>
<manvolnum>5</manvolnum>
</citerefentry> for more details about the configuration.
'';
example = literalExpression ''
{
nocjk = true;
loglevel = 5;
topdirs = [ "~/Downloads" "~/Documents" "~/projects" ];
"~/Downloads" = {
"skippedNames+" = [ "*.iso" ];
};
"~/projects" = {
"skippedNames+" = [ "node_modules" "target" "result" ];
};
}
'';
};
configDir = mkOption {
type = types.str;
default = "${config.home.homeDirectory}/.recoll";
defaultText = literalExpression "\${config.home.homeDirectory}/.recoll";
example = literalExpression "\${config.xdg.configHome}/recoll";
description = ''
The directory to contain Recoll configuration files. This will be set
as <literal>RECOLL_CONFDIR</literal>.
'';
};
};
config = mkIf cfg.enable {
assertions = [
(lib.hm.assertions.assertPlatform "services.recoll" pkgs
lib.platforms.linux)
];
home.packages = [ cfg.package ];
home.sessionVariables = { RECOLL_CONFDIR = cfg.configDir; };
home.file."${cfg.configDir}/recoll.conf".source =
settingsFormat.generate "recoll-conf-${config.home.username}"
cfg.settings;
systemd.user.services.recollindex = {
Unit = {
Description = "Recoll index update";
Documentation = [
"man:recoll"
"man:recollindex"
"https://www.lesbonscomptes.com/recoll/usermanual/"
];
};
Service = {
ExecStart = "${cfg.package}/bin/recollindex";
Environment = [ "RECOLL_CONFDIR=${escapeShellArg cfg.configDir}" ];
};
};
systemd.user.timers.recollindex = {
Unit = {
Description = "Recoll index update";
PartOf = [ "default.target" ];
};
Timer = {
Persistent = true;
OnCalendar = cfg.startAt;
};
Install.WantedBy = [ "timers.target" ];
};
};
}

View file

@ -171,6 +171,7 @@ import nmt {
./modules/services/picom
./modules/services/playerctld
./modules/services/polybar
./modules/services/recoll
./modules/services/redshift-gammastep
./modules/services/screen-locker
./modules/services/swayidle

View file

@ -0,0 +1,16 @@
nocjk = 0
skippedNames+ = node_modules
topdirs = ~/Downloads ~/Documents ~/library
underscoresasletter = 1
[~/library/projects]
skippedNames+ = .editorconfig .gitignore result flake.lock go.sum
[~/library/projects/software]
skippedNames+ = target result
[~/what-is-this-project]
skippedNames+ = whoa-there

View file

@ -0,0 +1,35 @@
{ config, ... }:
{
services.recoll = {
enable = true;
package = config.lib.test.mkStubPackage { };
configDir = "${config.xdg.configHome}/recoll";
settings = {
topdirs = [ "~/Downloads" "~/Documents" "~/library" ];
"skippedNames+" = [ "node_modules" ];
underscoresasletter = true;
nocjk = false;
"~/library/projects" = {
"skippedNames+" =
[ ".editorconfig" ".gitignore" "result" "flake.lock" "go.sum" ];
};
"~/library/projects/software" = {
"skippedNames+" = [ "target" "result" ];
};
"~/what-is-this-project" = { "skippedNames+" = [ "whoa-there" ]; };
};
};
nmt.script = ''
assertFileExists home-files/.config/systemd/user/recollindex.service
assertFileExists home-files/.config/systemd/user/recollindex.timer
assertFileExists home-files/.config/recoll/recoll.conf
assertFileContent home-files/.config/recoll/recoll.conf \
${./basic-configuration.conf}
'';
}

View file

@ -0,0 +1,25 @@
b = 10
d = 0
e = This should be the second to the last non-attrset value in the config.
g = This is coming from a list
[a]
foo = bar
[c]
a = This should appear as the second section.
aa = 1
b = 53
[f]
a = This should be second to the last for the attribute names with an attrset.
b = 3193
c = 0
d = Hello there
[foo]
bar = This should be the last attribute with an attrset.
baz = 42

View file

@ -0,0 +1,45 @@
# This is a test primarily concerned with the order of the configuration. The
# configuration is dynamically generated in alphabetical order of the top-level
# attribute names. Because of this, it is possible to override top-level
# attributes that are supposed to be configured in the top-level configuration.
{ config, ... }:
{
services.recoll = {
enable = true;
package = config.lib.test.mkStubPackage { };
settings = {
a = { foo = "bar"; };
b = 10;
c = {
a = "This should appear as the second section.";
b = 53;
aa = true;
};
d = false;
e =
"This should be the second to the last non-attrset value in the config.";
f = {
a =
"This should be second to the last for the attribute names with an attrset.";
b = 3193;
c = false;
d = [ "Hello" "there" ];
};
foo = {
bar = "This should be the last attribute with an attrset.";
baz = 42;
};
g = [ "This" "is" "coming" "from" "a" "list" ];
};
};
nmt.script = ''
assertFileExists home-files/.config/systemd/user/recollindex.service
assertFileExists home-files/.config/systemd/user/recollindex.timer
assertFileExists home-files/.recoll/recoll.conf
assertFileContent home-files/.recoll/recoll.conf \
${./config-format-order.conf}
'';
}

View file

@ -0,0 +1,4 @@
{
recoll-basic-configuration = ./basic-configuration.nix;
recoll-config-format-order = ./config-format-order.nix;
}