tldr.
Instead of using Nix’s ca-drv, which isn’t generally usable, use a script to content-address installed manpages to see if man-db cache needs to be rebuild.
Problem
Generate man-db cache by enabling documentation.man.generateCaches
is very slow. Average desktop NixOS can easily have 5k+ manpages installed, which can take man-db at least 10 seconds to generate cache from scratch. This is the method used in nixpkgs.
It’s irritating to see nixos-rebuild stuck on building man-cache
from time to time :<
Other solutions
ca-derivation
By making documentation.man.man-db.manualPages
a ca-drv, we can skip rebuild man-db cache if packages didn’t change. This method is also recommended in the option document.
However, ca-derivation
isn’t currently support by either cachix or garnix AFAIK, so it’s a no go for me since I depend on cachix heavily.
If ca-drv
become stable and usable one day, the method here won’t be necessary anymore.
man-db.service
man-db ships with a systemd service with a timer to update cache daily. Crucially, because man-db can do cache incrementally, it can be really fast.
However, man-db’s incremental cache ability relies on mtime, which totally doesn’t work on NixOS where all files are dated back to 1970.
In my workflow, the service is hooked up with sysinit-reactivation.target
so that each switch
will trigger the service. It’s too wasteful to rebuild cache every time, regardless of whether manpages have actually changed.
If man-db can archive incremental cache without mtime, it would be a perfect solution on NixOS though.
My solution
By combining the force of two, I made a prototype service that does content-address on the manpages directory, and if the hash changes, meaning the manpages also have changes, the cache will be regenerated, otherwise skip.
Such way man-cache
doesn’t block nixos-rebuild anymore, and I can still enjoy man with completions.
The logic of content-address is:
- Checksum all
*.gz
files in/run/current-system/sw/share/man/
- Sort alphanumerically
- Join checksums into one long string
- Checksum this long string
The full service module can be found at Nuran/nixos/documentation/default.nix at 6a4708cb2c4b46c97fd1ee98fd8f2b77df13bfe6 · MidAutumnMoon/Nuran · GitHub
Edit. 1
Deleting unneeded manpages can also help speed up building cache:
The snippet I’m using deletes multilingual manpages as well as man section 3 which contains mainly C functions that are not useful for me personally.
With this trick, I’d been able to shave the time of full cache build down to about 5s.