summary refs log tree commit diff
path: root/nixos/modules/misc
diff options
context:
space:
mode:
authorRobert Hensing <robert@roberthensing.nl>2022-01-22 16:39:00 +0100
committerRobert Hensing <robert@roberthensing.nl>2022-01-22 16:47:02 +0100
commit5d29853c389b52d75104415060fbeb2cd170a8fa (patch)
treeb23d91558604c4da61c6e16ba7478bcda3a1e3d7 /nixos/modules/misc
parent0b222173dba00680074ef9e98a5bad224f62967e (diff)
downloadnixpkgs-5d29853c389b52d75104415060fbeb2cd170a8fa.tar
nixpkgs-5d29853c389b52d75104415060fbeb2cd170a8fa.tar.gz
nixpkgs-5d29853c389b52d75104415060fbeb2cd170a8fa.tar.bz2
nixpkgs-5d29853c389b52d75104415060fbeb2cd170a8fa.tar.lz
nixpkgs-5d29853c389b52d75104415060fbeb2cd170a8fa.tar.xz
nixpkgs-5d29853c389b52d75104415060fbeb2cd170a8fa.tar.zst
nixpkgs-5d29853c389b52d75104415060fbeb2cd170a8fa.zip
nixos/documentation.nix: Use builtins.storePath when appropriate
Diffstat (limited to 'nixos/modules/misc')
-rw-r--r--nixos/modules/misc/documentation.nix82
1 files changed, 68 insertions, 14 deletions
diff --git a/nixos/modules/misc/documentation.nix b/nixos/modules/misc/documentation.nix
index 59ded4b0188..2afa43a3fe7 100644
--- a/nixos/modules/misc/documentation.nix
+++ b/nixos/modules/misc/documentation.nix
@@ -61,26 +61,80 @@ let
       in scrubbedEval.options;
     baseOptionsJSON =
       let
-        filter =
+        filterIntoStore =
           builtins.filterSource
             (n: t:
               (t == "directory" -> baseNameOf n != "tests")
               && (t == "file" -> hasSuffix ".nix" n)
             );
-        # When working directly from a checkout,
-        #   produce separate, smaller store paths
-        # When already in the store,
-        #   avoid copying; reuse the whole nixpkgs sources
+
+        # Figure out if Nix runs in pure evaluation mode. May return true in
+        # impure mode, but this is highly unlikely.
+        # We need to know because of https://github.com/NixOS/nix/issues/1888
+        # and https://github.com/NixOS/nix/issues/5868
+        isPureEval = builtins.getEnv "PATH" == "" && builtins.getEnv "_" == "";
+
+        # Return a nixpkgs subpath with minimal copying.
+        #
+        # The sources for the base options json derivation can come in one of
+        # two forms:
+        #   - single source: a store path with all of nixpkgs, postfix with
+        #     subpaths to access various directories. This has the benefit of
+        #     not creating copies of these subtrees in the Nix store, but
+        #     can cause unnecessary rebuilds if you update the Nixpkgs `pkgs`
+        #     tree often.
+        #   - split sources: multiple store paths with subdirectories of
+        #     nixpkgs that exclude the bulk of the pkgs directory.
+        #     This requires more copying and hashing during evaluation but
+        #     requires fewer files to be copied. This method produces fewer
+        #     unnecessary rebuilds of the base options json.
+        #
+        # Flake
+        #
+        # Flakes always put a copy of the full nixpkgs sources in the store,
+        # so we can use the "single source" method. This method is ideal
+        # for using nixpkgs as a dependency, as the base options json will be
+        # substitutable from cache.nixos.org.
+        #
+        # This requires that the `self.outPath` is wired into `pkgs` correctly,
+        # which is done for you if `pkgs` comes from the `lib.nixosSystem` or
+        # `legacyPackages` flake attributes.
+        #
+        # Other Nixpkgs invocation
+        #
+        # If you do not use the known-correct flake attributes, but rather
+        # invoke Nixpkgs yourself, set `config.path` to the correct path value,
+        # e.g. `import nixpkgs { config.path = nixpkgs; }`.
+        #
+        # Choosing between single or split source paths
+        #
+        # We make assumptions based on the type and contents of `pkgs.path`.
+        # By passing a different `config.path` to Nixpkgs, you can influence
+        # how your documentation cache is evaluated and rebuilt.
+        #
+        # Single source
+        #  - If pkgs.path is a string containing a store path, the code has no
+        #    choice but to create this store path, if it hasn't already been.
+        #    We assume that the "single source" method is most efficient.
+        #  - If pkgs.path is a path value containing that is a store path,
+        #    we try to convert it to a string with context without copying.
+        #    This occurs for example when nixpkgs was fetched and using its
+        #    default `config.path`, which is `./.`.
+        #    Nix currently does not allow this conversion when evaluating in
+        #    pure mode. If the conversion is not possible, we use the
+        #    "split source" method.
         #
-        # We can only avoid copying when pkgs.path is already a string. A path
-        # value can not be converted to a store path without rehashing it.
-        # builtins.storePath would be a solution but is currently off-limits
-        # because of https://github.com/NixOS/nix/issues/1888
-        #        and https://github.com/NixOS/nix/issues/5868
-        pull = dir:
-          if builtins.typeOf pkgs.path == "string" && isStorePath pkgs.path
-          then "${pkgs.path}/${dir}"
-          else filter "${toString pkgs.path}/${dir}";
+        # Split source
+        #  - If pkgs.path is a path value that is not a store path, we assume
+        #    that it's unlikely for all of nixpkgs to end up in the store for
+        #    other reasons and try to keep both the copying and rebuilds low.
+        pull =
+          if builtins.typeOf pkgs.path == "string" && isStorePath pkgs.path then
+            dir: "${pkgs.path}/${dir}"
+          else if !isPureEval && isStorePath pkgs.path then
+            dir: "${builtins.storePath pkgs.path}/${dir}"
+          else
+            dir: filterIntoStore "${toString pkgs.path}/${dir}";
       in
         pkgs.runCommand "lazy-options.json" {
           libPath = pull "lib";