{ config, lib, pkgs, baseModules, ... }: with lib; let cfg = config.documentation; /* For the purpose of generating docs, evaluate options with each derivation in `pkgs` (recursively) replaced by a fake with path "\${pkgs.attribute.path}". It isn't perfect, but it seems to cover a vast majority of use cases. Caveat: even if the package is reached by a different means, the path above will be shown and not e.g. `${config.services.foo.package}`. */ manual = import ../../doc/manual rec { inherit pkgs config; version = config.system.nixos.release; revision = "release-${version}"; options = let scrubbedEval = evalModules { modules = [ { nixpkgs.localSystem = config.nixpkgs.localSystem; } ] ++ baseModules; args = (config._module.args) // { modules = [ ]; }; specialArgs = { pkgs = scrubDerivations "pkgs" pkgs; }; }; scrubDerivations = namePrefix: pkgSet: mapAttrs (name: value: let wholeName = "${namePrefix}.${name}"; in if isAttrs value then scrubDerivations wholeName value // (optionalAttrs (isDerivation value) { outPath = "\${${wholeName}}"; }) else value ) pkgSet; in scrubbedEval.options; }; helpScript = pkgs.writeScriptBin "nixos-help" '' #! ${pkgs.runtimeShell} -e # Finds first executable browser in a colon-separated list. # (see how xdg-open defines BROWSER) browser="$( IFS=: ; for b in $BROWSER; do [ -n "$(type -P "$b" || true)" ] && echo "$b" && break done )" if [ -z "$browser" ]; then browser="$(type -P xdg-open || true)" if [ -z "$browser" ]; then browser="$(type -P w3m || true)" if [ -z "$browser" ]; then echo "$0: unable to start a web browser; please set \$BROWSER" exit 1 fi fi fi exec "$browser" ${manual.manualHTMLIndex} ''; desktopItem = pkgs.makeDesktopItem { name = "nixos-manual"; desktopName = "NixOS Manual"; genericName = "View NixOS documentation in a web browser"; icon = "nix-snowflake"; exec = "${helpScript}/bin/nixos-help"; categories = "System"; }; in { options = { documentation = { enable = mkOption { type = types.bool; default = true; description = '' Whether to install documentation of packages from into the generated system path. See "Multiple-output packages" chapter in the nixpkgs manual for more info. ''; # which is at ../../../doc/multiple-output.xml }; man.enable = mkOption { type = types.bool; default = true; description = '' Whether to install manual pages and the man command. This also includes "man" outputs. ''; }; info.enable = mkOption { type = types.bool; default = true; description = '' Whether to install info pages and the info command. This also includes "info" outputs. ''; }; doc.enable = mkOption { type = types.bool; default = true; description = '' Whether to install documentation distributed in packages' /share/doc. Usually plain text and/or HTML. This also includes "doc" outputs. ''; }; dev.enable = mkOption { type = types.bool; default = false; description = '' Whether to install documentation targeted at developers. This includes man pages targeted at developers if is set (this also includes "devman" outputs). This includes info pages targeted at developers if is set (this also includes "devinfo" outputs). This includes other pages targeted at developers if is set (this also includes "devdoc" outputs). ''; }; nixos.enable = mkOption { type = types.bool; default = true; description = '' Whether to install NixOS's own documentation. This includes man pages like configuration.nix 5 if is set. This includes the HTML manual and the nixos-help command if is set. ''; }; }; }; config = mkIf cfg.enable (mkMerge [ (mkIf cfg.man.enable { environment.systemPackages = [ pkgs.man-db ]; environment.pathsToLink = [ "/share/man" ]; environment.extraOutputsToInstall = [ "man" ] ++ optional cfg.dev.enable "devman"; }) (mkIf cfg.info.enable { environment.systemPackages = [ pkgs.texinfoInteractive ]; environment.pathsToLink = [ "/share/info" ]; environment.extraOutputsToInstall = [ "info" ] ++ optional cfg.dev.enable "devinfo"; environment.extraSetup = '' if [ -w $out/share/info ]; then shopt -s nullglob for i in $out/share/info/*.info $out/share/info/*.info.gz; do ${pkgs.texinfo}/bin/install-info $i $out/share/info/dir done fi ''; }) (mkIf cfg.doc.enable { # TODO(@oxij): put it here and remove from profiles? # environment.systemPackages = [ pkgs.w3m ]; # w3m-nox? environment.pathsToLink = [ "/share/doc" ]; environment.extraOutputsToInstall = [ "doc" ] ++ optional cfg.dev.enable "devdoc"; }) (mkIf cfg.nixos.enable { system.build.manual = manual; environment.systemPackages = [] ++ optional cfg.man.enable manual.manpages ++ optionals cfg.doc.enable ([ manual.manualHTML helpScript ] ++ optionals config.services.xserver.enable [ desktopItem pkgs.nixos-icons ]); services.mingetty.helpLine = mkIf cfg.doc.enable ( "\nRun `nixos-help` " + optionalString config.services.nixosManual.showManual "or press " + "for the NixOS manual." ); }) ]); }