diff options
author | Eelco Dolstra <edolstra@gmail.com> | 2020-06-11 14:40:21 +0200 |
---|---|---|
committer | Eelco Dolstra <edolstra@gmail.com> | 2020-06-11 14:40:21 +0200 |
commit | 0c62b4ad0f80d2801a7e7caabf20cc8e50182540 (patch) | |
tree | 583ef5ad90342e0d789d21ec748d650c91367992 /src/libexpr/flake/call-flake.nix | |
parent | 195ed43b60cc2a2a18adc24e272a3d90466c9bc7 (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.nix | 29 |
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 |