diff --git a/lib/attrsets.nix b/lib/attrsets.nix index 82bea7af31f..d91d7a0cd47 100644 --- a/lib/attrsets.nix +++ b/lib/attrsets.nix @@ -469,6 +469,7 @@ rec { getBin = getOutput "bin"; getLib = getOutput "lib"; getDev = getOutput "dev"; + getMan = getOutput "man"; /* Pick the outputs of packages to place in buildInputs */ chooseDevOutputs = drvs: builtins.map getDev drvs; diff --git a/lib/default.nix b/lib/default.nix index e7f59a67abb..7387e9d9f1f 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -77,7 +77,7 @@ let genAttrs isDerivation toDerivation optionalAttrs zipAttrsWithNames zipAttrsWith zipAttrs recursiveUpdateUntil recursiveUpdate matchAttrs overrideExisting getOutput getBin - getLib getDev chooseDevOutputs zipWithNames zip + getLib getDev getMan chooseDevOutputs zipWithNames zip recurseIntoAttrs dontRecurseIntoAttrs; inherit (lists) singleton forEach foldr fold foldl foldl' imap0 imap1 concatMap flatten remove findSingle findFirst any all count diff --git a/nixos/doc/manual/release-notes/rl-2009.xml b/nixos/doc/manual/release-notes/rl-2009.xml index 9bbbecc0569..31cabce1d53 100644 --- a/nixos/doc/manual/release-notes/rl-2009.xml +++ b/nixos/doc/manual/release-notes/rl-2009.xml @@ -110,6 +110,15 @@ systemd.services.mysql.serviceConfig.ReadWritePaths = [ "/var/data" ]; + + + Two new option documentation.man.generateCaches + has been added to automatically generate the man-db caches, which are needed by utilities + like whatis and apropos. The caches are generated during the build of + the NixOS configuration: since this can be expensive when a large number of packages are installed, the + feature is disabled by default. + + diff --git a/nixos/modules/misc/documentation.nix b/nixos/modules/misc/documentation.nix index 7ad4be9a02e..71a40b4f4d6 100644 --- a/nixos/modules/misc/documentation.nix +++ b/nixos/modules/misc/documentation.nix @@ -102,6 +102,16 @@ in ''; }; + man.generateCaches = mkOption { + type = types.bool; + default = false; + description = '' + Whether to generate the manual page index caches using + mandb(8). This allows searching for a page or + keyword using utilities like apropos(1). + ''; + }; + info.enable = mkOption { type = types.bool; default = true; @@ -187,7 +197,33 @@ in environment.systemPackages = [ pkgs.man-db ]; environment.pathsToLink = [ "/share/man" ]; environment.extraOutputsToInstall = [ "man" ] ++ optional cfg.dev.enable "devman"; - environment.etc."man.conf".source = "${pkgs.man-db}/etc/man_db.conf"; + environment.etc."man_db.conf".text = + let + manualPages = pkgs.buildEnv { + name = "man-paths"; + paths = config.environment.systemPackages; + pathsToLink = [ "/share/man" ]; + extraOutputsToInstall = ["man"]; + ignoreCollisions = true; + }; + manualCache = pkgs.runCommandLocal "man-cache" { } + '' + echo "MANDB_MAP ${manualPages}/share/man $out" > man.conf + ${pkgs.man-db}/bin/mandb -C man.conf -psc + ''; + 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 + + ${optionalString cfg.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 + ''; }) (mkIf cfg.info.enable { diff --git a/pkgs/tools/misc/man-db/default.nix b/pkgs/tools/misc/man-db/default.nix index 7b8835622c8..f5cbef8b022 100644 --- a/pkgs/tools/misc/man-db/default.nix +++ b/pkgs/tools/misc/man-db/default.nix @@ -15,18 +15,17 @@ stdenv.mkDerivation rec { buildInputs = [ libpipeline db groff ]; # (Yes, 'groff' is both native and build input) checkInputs = [ libiconv /* for 'iconv' binary */ ]; + patches = [ ./systemwide-man-db-conf.patch ]; + postPatch = '' # Remove all mandatory manpaths. Nixpkgs makes no requirements on # these directories existing. sed -i 's/^MANDATORY_MANPATH/# &/' src/man_db.conf.in - # Add Nixpkgs and NixOS-related manpaths - echo "MANPATH_MAP /run/current-system/sw/bin /run/current-system/sw/share/man" >> src/man_db.conf.in - echo "MANPATH_MAP /run/wrappers/bin /run/current-system/sw/share/man" >> src/man_db.conf.in + # Add Nix-related manpaths echo "MANPATH_MAP /nix/var/nix/profiles/default/bin /nix/var/nix/profiles/default/share/man" >> src/man_db.conf.in # Add mandb locations for the above - echo "MANDB_MAP /run/current-system/sw/share/man /var/cache/man/nixos" >> src/man_db.conf.in echo "MANDB_MAP /nix/var/nix/profiles/default/share/man /var/cache/man/nixpkgs" >> src/man_db.conf.in ''; @@ -34,7 +33,6 @@ stdenv.mkDerivation rec { "--disable-setuid" "--disable-cache-owner" "--localstatedir=/var" - # Don't try /etc/man_db.conf by default, so we avoid error messages. "--with-config-file=${placeholder "out"}/etc/man_db.conf" "--with-systemdtmpfilesdir=${placeholder "out"}/lib/tmpfiles.d" "--with-systemdsystemunitdir=${placeholder "out"}/lib/systemd/system" diff --git a/pkgs/tools/misc/man-db/systemwide-man-db-conf.patch b/pkgs/tools/misc/man-db/systemwide-man-db-conf.patch new file mode 100644 index 00000000000..2d4477776bb --- /dev/null +++ b/pkgs/tools/misc/man-db/systemwide-man-db-conf.patch @@ -0,0 +1,39 @@ +commit 9089291006a4258c39c75a920ad536b61504251a +Author: rnhmjoj +Date: Fri May 1 19:32:15 2020 +0200 + + check for systemwide man_db.conf before the bundled one + +diff --git a/src/manp.c b/src/manp.c +index 5441339..0bbf566 100644 +--- a/src/manp.c ++++ b/src/manp.c +@@ -841,18 +841,24 @@ void read_config_file (bool optional) + } + + if (getenv ("MAN_TEST_DISABLE_SYSTEM_CONFIG") == NULL) { +- config_file = fopen (CONFIG_FILE, "r"); ++ const char *config_filepath; ++ if (access ("/etc/man_db.conf", F_OK) != -1) { ++ config_filepath = "/etc/man_db.conf"; ++ } else { ++ config_filepath = CONFIG_FILE; ++ } ++ config_file = fopen (config_filepath, "r"); + if (config_file == NULL) { + if (optional) + debug ("can't open %s; continuing anyway\n", +- CONFIG_FILE); ++ config_filepath); + else + error (FAIL, 0, + _("can't open the manpath " + "configuration file %s"), +- CONFIG_FILE); ++ config_filepath); + } else { +- debug ("From the config file %s:\n", CONFIG_FILE); ++ debug ("From the config file %s:\n", config_filepath); + + add_to_dirlist (config_file, 0); + fclose (config_file);