aboutsummaryrefslogtreecommitdiff
path: root/src/libexpr/flake/call-flake.nix
diff options
context:
space:
mode:
Diffstat (limited to 'src/libexpr/flake/call-flake.nix')
-rw-r--r--src/libexpr/flake/call-flake.nix56
1 files changed, 56 insertions, 0 deletions
diff --git a/src/libexpr/flake/call-flake.nix b/src/libexpr/flake/call-flake.nix
new file mode 100644
index 000000000..932ac5e90
--- /dev/null
+++ b/src/libexpr/flake/call-flake.nix
@@ -0,0 +1,56 @@
+lockFileStr: rootSrc: rootSubdir:
+
+let
+
+ lockFile = builtins.fromJSON lockFileStr;
+
+ allNodes =
+ 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: 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
+ assert builtins.isFunction flake.outputs;
+ result
+ else
+ sourceInfo
+ )
+ lockFile.nodes;
+
+in allNodes.${lockFile.root}