aboutsummaryrefslogtreecommitdiff
path: root/src/libexpr/flake/call-flake.nix
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2020-06-11 14:40:21 +0200
committerEelco Dolstra <edolstra@gmail.com>2020-06-11 14:40:21 +0200
commit0c62b4ad0f80d2801a7e7caabf20cc8e50182540 (patch)
tree583ef5ad90342e0d789d21ec748d650c91367992 /src/libexpr/flake/call-flake.nix
parent195ed43b60cc2a2a18adc24e272a3d90466c9bc7 (diff)
Represent 'follows' inputs explicitly in the lock file
This fixes an issue where lockfile generation was not idempotent: after updating a lockfile, a "follows" node would end up pointing to a new copy of the node, rather than to the original node.
Diffstat (limited to 'src/libexpr/flake/call-flake.nix')
-rw-r--r--src/libexpr/flake/call-flake.nix29
1 files changed, 28 insertions, 1 deletions
diff --git a/src/libexpr/flake/call-flake.nix b/src/libexpr/flake/call-flake.nix
index 2084e3fb3..932ac5e90 100644
--- a/src/libexpr/flake/call-flake.nix
+++ b/src/libexpr/flake/call-flake.nix
@@ -8,14 +8,41 @@ let
builtins.mapAttrs
(key: node:
let
+
sourceInfo =
if key == lockFile.root
then rootSrc
else fetchTree (node.info or {} // removeAttrs node.locked ["dir"]);
+
subdir = if key == lockFile.root then rootSubdir else node.locked.dir or "";
+
flake = import (sourceInfo + (if subdir != "" then "/" else "") + subdir + "/flake.nix");
- inputs = builtins.mapAttrs (inputName: key: allNodes.${key}) (node.inputs or {});
+
+ inputs = builtins.mapAttrs
+ (inputName: inputSpec: allNodes.${resolveInput inputSpec})
+ (node.inputs or {});
+
+ # Resolve a input spec into a node name. An input spec is
+ # either a node name, or a 'follows' path from the root
+ # node.
+ resolveInput = inputSpec:
+ if builtins.isList inputSpec
+ then getInputByPath lockFile.root inputSpec
+ else inputSpec;
+
+ # Follow an input path (e.g. ["dwarffs" "nixpkgs"]) from the
+ # root node, returning the final node.
+ getInputByPath = nodeName: path:
+ if path == []
+ then nodeName
+ else
+ getInputByPath
+ # Since this could be a 'follows' input, call resolveInput.
+ (resolveInput lockFile.nodes.${nodeName}.inputs.${builtins.head path})
+ (builtins.tail path);
+
outputs = flake.outputs (inputs // { self = result; });
+
result = outputs // sourceInfo // { inherit inputs; inherit outputs; inherit sourceInfo; };
in
if node.flake or true then