200 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
			
		
		
	
	
			200 lines
		
	
	
		
			6.6 KiB
		
	
	
	
		
			Nix
		
	
	
	
	
	
{ 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
 | 
						|
          <option>environment.systemPackages</option> 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 <command>man</command> command.
 | 
						|
          This also includes "man" outputs.
 | 
						|
        '';
 | 
						|
      };
 | 
						|
 | 
						|
      info.enable = mkOption {
 | 
						|
        type = types.bool;
 | 
						|
        default = true;
 | 
						|
        description = ''
 | 
						|
          Whether to install info pages and the <command>info</command> command.
 | 
						|
          This also includes "info" outputs.
 | 
						|
        '';
 | 
						|
      };
 | 
						|
 | 
						|
      doc.enable = mkOption {
 | 
						|
        type = types.bool;
 | 
						|
        default = true;
 | 
						|
        description = ''
 | 
						|
          Whether to install documentation distributed in packages' <literal>/share/doc</literal>.
 | 
						|
          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.
 | 
						|
          <itemizedlist>
 | 
						|
          <listitem><para>This includes man pages targeted at developers if <option>man.enable</option> is
 | 
						|
                    set (this also includes "devman" outputs).</para></listitem>
 | 
						|
          <listitem><para>This includes info pages targeted at developers if <option>info.enable</option>
 | 
						|
                    is set (this also includes "devinfo" outputs).</para></listitem>
 | 
						|
          <listitem><para>This includes other pages targeted at developers if <option>doc.enable</option>
 | 
						|
                    is set (this also includes "devdoc" outputs).</para></listitem>
 | 
						|
          </itemizedlist>
 | 
						|
        '';
 | 
						|
      };
 | 
						|
 | 
						|
      nixos.enable = mkOption {
 | 
						|
        type = types.bool;
 | 
						|
        default = true;
 | 
						|
        description = ''
 | 
						|
          Whether to install NixOS's own documentation.
 | 
						|
          <itemizedlist>
 | 
						|
          <listitem><para>This includes man pages like
 | 
						|
                    <citerefentry><refentrytitle>configuration.nix</refentrytitle>
 | 
						|
                    <manvolnum>5</manvolnum></citerefentry> if <option>man.enable</option> is
 | 
						|
                    set.</para></listitem>
 | 
						|
          <listitem><para>This includes the HTML manual and the <command>nixos-help</command> command if
 | 
						|
                    <option>doc.enable</option> is set.</para></listitem>
 | 
						|
          </itemizedlist>
 | 
						|
        '';
 | 
						|
      };
 | 
						|
 | 
						|
    };
 | 
						|
 | 
						|
  };
 | 
						|
 | 
						|
  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 <Alt-F${toString config.services.nixosManual.ttyNumber}> "
 | 
						|
        + "for the NixOS manual."
 | 
						|
      );
 | 
						|
    })
 | 
						|
 | 
						|
  ]);
 | 
						|
 | 
						|
}
 |