nixos/man-db: add option to generate cache at runtime (#488395)

This commit is contained in:
Doron Behar
2026-02-19 15:42:47 +00:00
committed by GitHub
4 changed files with 94 additions and 40 deletions
+15 -1
View File
@@ -228,6 +228,10 @@ in
(mkRenamedOptionModule [ "programs" "info" "enable" ] [ "documentation" "info" "enable" ])
(mkRenamedOptionModule [ "programs" "man" "enable" ] [ "documentation" "man" "enable" ])
(mkRenamedOptionModule [ "services" "nixosManual" "enable" ] [ "documentation" "nixos" "enable" ])
(mkRenamedOptionModule
[ "documentation" "man" "generateCaches" ]
[ "documentation" "man" "cache" "enable" ]
)
(mkRemovedOptionModule [
"documentation"
"nixos"
@@ -261,7 +265,7 @@ in
'';
};
man.generateCaches = mkOption {
man.cache.enable = mkOption {
type = types.bool;
default = false;
description = ''
@@ -273,6 +277,16 @@ in
'';
};
man.cache.generateAtRuntime = mkOption {
type = types.bool;
default = false;
description = ''
Whether to generate the manual page index caches at runtime using
a systemd service. Note that this is currently only supported by the
man-db module.
'';
};
info.enable = mkOption {
type = types.bool;
default = true;
+75 -36
View File
@@ -7,13 +7,14 @@
let
cfg = config.documentation.man.man-db;
cfgm = config.documentation.man;
in
{
options = {
documentation.man.man-db = {
enable = lib.mkEnableOption "man-db as the default man page viewer" // {
default = config.documentation.man.enable;
default = cfgm.enable;
defaultText = lib.literalExpression "config.documentation.man.enable";
example = false;
};
@@ -39,7 +40,7 @@ in
};
defaultText = lib.literalMD "all man pages in {option}`config.environment.systemPackages`";
description = ''
The manual pages to generate caches for if {option}`documentation.man.generateCaches`
The manual pages to generate caches for if {option}`documentation.man.cache.enable`
is enabled. Must be a path to a directory with man pages under
`/share/man`; see the source for an example.
Advanced users can make this a content-addressed derivation to save a few rebuilds.
@@ -65,41 +66,79 @@ in
)
];
config = lib.mkIf cfg.enable {
environment.systemPackages = [ cfg.package ];
environment.etc."man_db.conf".text =
let
# We unfortunately cant use the customized `cfg.package` when
# crosscompiling. Instead we detect that situation and work
# around it by using the vanilla one, like the OpenSSH module.
buildPackage =
if pkgs.stdenv.buildPlatform.canExecute pkgs.stdenv.hostPlatform then
config = lib.mkIf cfg.enable (
lib.mkMerge [
{
environment.systemPackages = [ cfg.package ];
environment.etc."man_db.conf".text =
let
# We unfortunately cant use the customized `cfg.package` when
# crosscompiling. Instead we detect that situation and work
# around it by using the vanilla one, like the OpenSSH module.
buildPackage =
if pkgs.stdenv.buildPlatform.canExecute pkgs.stdenv.hostPlatform then
cfg.package
else
pkgs.buildPackages.man-db;
manualCache =
if (!cfgm.cache.generateAtRuntime) then
pkgs.runCommand "man-cache"
{
nativeBuildInputs = [ buildPackage ];
preferLocalBuild = true;
}
''
echo "MANDB_MAP ${cfg.manualPages}/share/man $out" > man.conf
mandb -C man.conf -pscq
''
else
"/var/cache/man/nixos-mandb";
in
''
# Manual pages paths for NixOS
MANPATH_MAP /run/current-system/sw/bin /run/current-system/sw/share/man
MANPATH_MAP /run/wrappers/bin /run/current-system/sw/share/man
${lib.optionalString cfgm.cache.enable ''
# Manual pages caches for NixOS
MANDB_MAP /run/current-system/sw/share/man ${manualCache}
''}
'';
}
(lib.mkIf (cfgm.enable && cfgm.cache.generateAtRuntime) {
users.users.mandb = {
isSystemUser = true;
group = "mandb";
};
users.groups.mandb = { };
systemd.services.mandb = {
path = [
cfg.package
else
pkgs.buildPackages.man-db;
pkgs.rsync
];
script = ''
rsync \
--checksum --recursive --copy-links --delete --no-times --no-perms --chmod=+w \
${cfg.manualPages}/share/man/ "$CACHE_DIRECTORY/nixos-manpages"
manualCache =
pkgs.runCommand "man-cache"
{
nativeBuildInputs = [ buildPackage ];
preferLocalBuild = true;
}
''
echo "MANDB_MAP ${cfg.manualPages}/share/man $out" > man.conf
mandb -C man.conf -pscq
'';
in
''
# Manual pages paths for NixOS
MANPATH_MAP /run/current-system/sw/bin /run/current-system/sw/share/man
MANPATH_MAP /run/wrappers/bin /run/current-system/sw/share/man
echo "MANDB_MAP $CACHE_DIRECTORY/nixos-manpages $CACHE_DIRECTORY/nixos-mandb" \
> "$RUNTIME_DIRECTORY/man.conf"
${lib.optionalString config.documentation.man.generateCaches ''
# Generated manual pages cache for NixOS (immutable)
MANDB_MAP /run/current-system/sw/share/man ${manualCache}
''}
# Manual pages caches for NixOS
MANDB_MAP /run/current-system/sw/share/man /var/cache/man/nixos
'';
};
mandb -C "$RUNTIME_DIRECTORY/man.conf" -q
'';
serviceConfig = {
CacheDirectory = "man";
RuntimeDirectory = "mandb";
User = "mandb";
BindReadOnlyPaths = [ "/dev/null:/etc/man_db.conf" ]; # mandb will still read /etc/man_db.conf if it exists, even when setting -C path/to/config.conf
ProtectSystem = "strict";
};
wantedBy = [ "default.target" ];
};
})
]
);
}
+2 -2
View File
@@ -60,7 +60,7 @@ in
apply = makeLeadingSlashes;
description = ''
Change the paths where mandoc {manpage}`makewhatis(8)`generates the
manual page index caches. {option}`documentation.man.generateCaches`
manual page index caches. {option}`documentation.man.cache.enable`
should be enabled to allow cache generation. This list should only
include the paths to manpages installed in the system configuration,
i. e. /run/current-system/sw/share/man. {manpage}`makewhatis(8)`
@@ -215,7 +215,7 @@ in
# create mandoc.db for whatis(1), apropos(1) and man(1) -k
# TODO(@sternenseemman): fix symlinked directories not getting indexed,
# see: https://inbox.vuxu.org/mandoc-tech/20210906171231.GF83680@athene.usta.de/T/#e85f773c1781e3fef85562b2794f9cad7b2909a3c
extraSetup = lib.mkIf config.documentation.man.generateCaches ''
extraSetup = lib.mkIf config.documentation.man.cache.enable ''
for man_path in ${
lib.concatMapStringsSep " " (path: "$out" + lib.escapeShellArg path) cfg.cachePath
}
+2 -1
View File
@@ -169,7 +169,8 @@ in
programs.fish.shellAliases = lib.mapAttrs (name: lib.mkDefault) cfge.shellAliases;
# Required for man completions
documentation.man.generateCaches = lib.mkDefault true;
documentation.man.cache.enable = lib.mkDefault true;
documentation.man.cache.generateAtRuntime = lib.mkDefault true;
environment = lib.mkMerge [
(lib.mkIf cfg.useBabelfish {