mirror of
https://github.com/NixOS/nix
synced 2025-06-28 22:01:15 +02:00
Move call-flake.nix to nix-flake
As suggested by Ericson2314 in review https://github.com/NixOS/nix/pull/12759#issuecomment-2755352343
This commit is contained in:
parent
6fc9651d57
commit
0c75581d8b
7 changed files with 34 additions and 10 deletions
96
src/libflake/call-flake.nix
Normal file
96
src/libflake/call-flake.nix
Normal file
|
@ -0,0 +1,96 @@
|
|||
# This is a helper to callFlake() to lazily fetch flake inputs.
|
||||
|
||||
# The contents of the lock file, in JSON format.
|
||||
lockFileStr:
|
||||
|
||||
# A mapping of lock file node IDs to { sourceInfo, subdir } attrsets,
|
||||
# with sourceInfo.outPath providing an SourceAccessor to a previously
|
||||
# fetched tree. This is necessary for possibly unlocked inputs, in
|
||||
# particular the root input, but also --override-inputs pointing to
|
||||
# unlocked trees.
|
||||
overrides:
|
||||
|
||||
# This is `prim_fetchFinalTree`.
|
||||
fetchTreeFinal:
|
||||
|
||||
let
|
||||
|
||||
lockFile = builtins.fromJSON lockFileStr;
|
||||
|
||||
# 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 attrpath (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);
|
||||
|
||||
allNodes = builtins.mapAttrs (
|
||||
key: node:
|
||||
let
|
||||
|
||||
parentNode = allNodes.${getInputByPath lockFile.root node.parent};
|
||||
|
||||
sourceInfo =
|
||||
if overrides ? ${key} then
|
||||
overrides.${key}.sourceInfo
|
||||
else if node.locked.type == "path" && builtins.substring 0 1 node.locked.path != "/" then
|
||||
parentNode.sourceInfo
|
||||
// {
|
||||
outPath = parentNode.outPath + ("/" + node.locked.path);
|
||||
}
|
||||
else
|
||||
# FIXME: remove obsolete node.info.
|
||||
# Note: lock file entries are always final.
|
||||
fetchTreeFinal (node.info or { } // removeAttrs node.locked [ "dir" ]);
|
||||
|
||||
subdir = overrides.${key}.dir or node.locked.dir or "";
|
||||
|
||||
outPath = sourceInfo + ((if subdir == "" then "" else "/") + subdir);
|
||||
|
||||
flake = import (outPath + "/flake.nix");
|
||||
|
||||
inputs = builtins.mapAttrs (inputName: inputSpec: allNodes.${resolveInput inputSpec}) (
|
||||
node.inputs or { }
|
||||
);
|
||||
|
||||
outputs = flake.outputs (inputs // { self = result; });
|
||||
|
||||
result =
|
||||
outputs
|
||||
# We add the sourceInfo attribute for its metadata, as they are
|
||||
# relevant metadata for the flake. However, the outPath of the
|
||||
# sourceInfo does not necessarily match the outPath of the flake,
|
||||
# as the flake may be in a subdirectory of a source.
|
||||
# This is shadowed in the next //
|
||||
// sourceInfo
|
||||
// {
|
||||
# This shadows the sourceInfo.outPath
|
||||
inherit outPath;
|
||||
|
||||
inherit inputs;
|
||||
inherit outputs;
|
||||
inherit sourceInfo;
|
||||
_type = "flake";
|
||||
};
|
||||
|
||||
in
|
||||
if node.flake or true then
|
||||
assert builtins.isFunction flake.outputs;
|
||||
result
|
||||
else
|
||||
sourceInfo
|
||||
) lockFile.nodes;
|
||||
|
||||
in
|
||||
allNodes.${lockFile.root}
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include "memory-source-accessor.hh"
|
||||
|
||||
namespace nix {
|
||||
|
||||
using namespace flake;
|
||||
|
@ -921,6 +923,25 @@ LockedFlake lockFlake(
|
|||
}
|
||||
}
|
||||
|
||||
static ref<SourceAccessor> makeInternalFS() {
|
||||
auto internalFS = make_ref<MemorySourceAccessor>(MemorySourceAccessor {});
|
||||
internalFS->setPathDisplay("«flakes-internal»", "");
|
||||
internalFS->addFile(
|
||||
CanonPath("call-flake.nix"),
|
||||
#include "call-flake.nix.gen.hh"
|
||||
);
|
||||
return internalFS;
|
||||
}
|
||||
|
||||
static auto internalFS = makeInternalFS();
|
||||
|
||||
static Value * requireInternalFile(EvalState & state, CanonPath path) {
|
||||
SourcePath p {internalFS, path};
|
||||
auto v = state.allocValue();
|
||||
state.evalFile(p, *v); // has caching
|
||||
return v;
|
||||
}
|
||||
|
||||
void callFlake(EvalState & state,
|
||||
const LockedFlake & lockedFlake,
|
||||
Value & vRes)
|
||||
|
@ -960,8 +981,7 @@ void callFlake(EvalState & state,
|
|||
|
||||
auto & vOverrides = state.allocValue()->mkAttrs(overrides);
|
||||
|
||||
auto vCallFlake = state.allocValue();
|
||||
state.evalFile(state.callFlakeInternal, *vCallFlake);
|
||||
Value * vCallFlake = requireInternalFile(state, CanonPath("call-flake.nix"));
|
||||
|
||||
auto vLocks = state.allocValue();
|
||||
vLocks->mkString(lockFileStr);
|
||||
|
|
|
@ -39,6 +39,15 @@ add_project_arguments(
|
|||
|
||||
subdir('nix-meson-build-support/common')
|
||||
|
||||
subdir('nix-meson-build-support/generate-header')
|
||||
|
||||
generated_headers = []
|
||||
foreach header : [
|
||||
'call-flake.nix',
|
||||
]
|
||||
generated_headers += gen_header.process(header)
|
||||
endforeach
|
||||
|
||||
sources = files(
|
||||
'flake/config.cc',
|
||||
'flake/flake.cc',
|
||||
|
@ -62,6 +71,7 @@ headers = files(
|
|||
this_library = library(
|
||||
'nixflake',
|
||||
sources,
|
||||
generated_headers,
|
||||
dependencies : deps_public + deps_private + deps_other,
|
||||
prelink : true, # For C++ static initializers
|
||||
install : true,
|
||||
|
|
|
@ -28,6 +28,7 @@ mkMesonLibrary (finalAttrs: {
|
|||
../../.version
|
||||
./.version
|
||||
./meson.build
|
||||
./call-flake.nix
|
||||
(fileset.fileFilter (file: file.hasExt "cc") ./.)
|
||||
(fileset.fileFilter (file: file.hasExt "hh") ./.)
|
||||
];
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue