import ./make-test-python.nix ({ pkgs, lib, ... }: let manImplementations = [ "mandoc" "man-db" ]; machineNames = builtins.map machineSafe manImplementations; makeConfig = useImpl: { # Note: mandoc currently can't index symlinked section directories. # So if a man section comes from one package exclusively (e. g. # 1p from man-pages-posix and 2 from man-pages), it isn't searchable. environment.systemPackages = [ pkgs.man-pages pkgs.openssl pkgs.libunwind ]; documentation = { enable = true; nixos.enable = lib.mkForce true; dev.enable = true; man = { enable = true; generateCaches = true; } // lib.listToAttrs (builtins.map (impl: { name = impl; value = { enable = useImpl == impl; }; }) manImplementations); }; }; machineSafe = builtins.replaceStrings [ "-" ] [ "_" ]; in { name = "man"; meta.maintainers = [ lib.maintainers.sternenseemann ]; nodes = lib.listToAttrs (builtins.map (i: { name = machineSafe i; value = makeConfig i; }) manImplementations); testScript = '' import re start_all() def match_man_k(page, section, haystack): """ Check if the man page {page}({section}) occurs in the output of `man -k` given as haystack. Note: This is not super reliable, e. g. it can't deal with man pages that are in multiple sections. """ for line in haystack.split("\n"): # man -k can look like this: # page(3) - bla # page (3) - bla # pagea, pageb (3, 3P) - foo # pagea, pageb, pagec(3) - bar pages = line.split("(")[0] sections = re.search("\\([a-zA-Z1-9, ]+\\)", line) if sections is None: continue else: sections = sections.group(0)[1:-1] if page in pages and f'{section}' in sections: return True return False '' + lib.concatMapStrings (machine: '' with subtest("Test direct man page lookups in ${machine}"): # man works ${machine}.succeed("man man > /dev/null") # devman works ${machine}.succeed("man 3 libunwind > /dev/null") # NixOS configuration man page is installed ${machine}.succeed("man configuration.nix > /dev/null") with subtest("Test generateCaches via man -k in ${machine}"): expected = [ ("openssl", "ssl", 3), ("unwind", "libunwind", 3), ("user", "useradd", 8), ("user", "userdel", 8), ("mem", "free", 3), ("mem", "free", 1), ] for (keyword, page, section) in expected: matches = ${machine}.succeed(f"man -k {keyword}") if not match_man_k(page, section, matches): raise Exception(f"{page}({section}) missing in matches: {matches}") '') machineNames; })