Only provide builtin.{getFlake,fetchClosure} is the corresponding experimental feature is enabled
This allows writing fallback code like if builtins ? fetchClosure then builtins.fetchClose { ... } else builtins.storePath ...
This commit is contained in:
parent
55bc524019
commit
86b05ccd54
8 changed files with 31 additions and 39 deletions
|
@ -5,9 +5,12 @@
|
|||
* `nix store make-content-addressable` has been renamed to `nix store
|
||||
make-content-addressed`.
|
||||
|
||||
* New builtin function `builtins.fetchClosure` that copies a closure
|
||||
from a binary cache at evaluation time and rewrites it to
|
||||
content-addressed form (if it isn't already). Like
|
||||
* New experimental builtin function `builtins.fetchClosure` that
|
||||
copies a closure from a binary cache at evaluation time and rewrites
|
||||
it to content-addressed form (if it isn't already). Like
|
||||
`builtins.storePath`, this allows importing pre-built store paths;
|
||||
the difference is that it doesn't require the user to configure
|
||||
binary caches and trusted public keys.
|
||||
|
||||
This function is only available if you enable the experimental
|
||||
feature `fetch-closure`.
|
||||
|
|
|
@ -507,23 +507,6 @@ EvalState::~EvalState()
|
|||
}
|
||||
|
||||
|
||||
void EvalState::requireExperimentalFeatureOnEvaluation(
|
||||
const ExperimentalFeature & feature,
|
||||
const std::string_view fName,
|
||||
const Pos & pos)
|
||||
{
|
||||
if (!settings.isExperimentalFeatureEnabled(feature)) {
|
||||
throw EvalError({
|
||||
.msg = hintfmt(
|
||||
"Cannot call '%2%' because experimental Nix feature '%1%' is disabled. You can enable it via '--extra-experimental-features %1%'.",
|
||||
feature,
|
||||
fName
|
||||
),
|
||||
.errPos = pos
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void EvalState::allowPath(const Path & path)
|
||||
{
|
||||
if (allowedPaths)
|
||||
|
|
|
@ -149,12 +149,6 @@ public:
|
|||
std::shared_ptr<Store> buildStore = nullptr);
|
||||
~EvalState();
|
||||
|
||||
void requireExperimentalFeatureOnEvaluation(
|
||||
const ExperimentalFeature &,
|
||||
const std::string_view fName,
|
||||
const Pos & pos
|
||||
);
|
||||
|
||||
void addToSearchPath(const std::string & s);
|
||||
|
||||
SearchPath getSearchPath() { return searchPath; }
|
||||
|
|
|
@ -706,8 +706,6 @@ void callFlake(EvalState & state,
|
|||
|
||||
static void prim_getFlake(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||
{
|
||||
state.requireExperimentalFeatureOnEvaluation(Xp::Flakes, "builtins.getFlake", pos);
|
||||
|
||||
std::string flakeRefS(state.forceStringNoCtx(*args[0], pos));
|
||||
auto flakeRef = parseFlakeRef(flakeRefS, {}, true);
|
||||
if (evalSettings.pureEval && !flakeRef.input.isLocked())
|
||||
|
@ -723,7 +721,12 @@ static void prim_getFlake(EvalState & state, const Pos & pos, Value * * args, Va
|
|||
v);
|
||||
}
|
||||
|
||||
static RegisterPrimOp r2("__getFlake", 1, prim_getFlake);
|
||||
static RegisterPrimOp r2({
|
||||
.name = "__getFlake",
|
||||
.args = {"args"},
|
||||
.fun = prim_getFlake,
|
||||
.experimentalFeature = Xp::Flakes,
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -3814,7 +3814,7 @@ RegisterPrimOp::RegisterPrimOp(std::string name, size_t arity, PrimOpFun fun)
|
|||
.name = name,
|
||||
.args = {},
|
||||
.arity = arity,
|
||||
.fun = fun
|
||||
.fun = fun,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -3886,13 +3886,17 @@ void EvalState::createBaseEnv()
|
|||
|
||||
if (RegisterPrimOp::primOps)
|
||||
for (auto & primOp : *RegisterPrimOp::primOps)
|
||||
addPrimOp({
|
||||
.fun = primOp.fun,
|
||||
.arity = std::max(primOp.args.size(), primOp.arity),
|
||||
.name = symbols.create(primOp.name),
|
||||
.args = primOp.args,
|
||||
.doc = primOp.doc,
|
||||
});
|
||||
if (!primOp.experimentalFeature
|
||||
|| settings.isExperimentalFeatureEnabled(*primOp.experimentalFeature))
|
||||
{
|
||||
addPrimOp({
|
||||
.fun = primOp.fun,
|
||||
.arity = std::max(primOp.args.size(), primOp.arity),
|
||||
.name = symbols.create(primOp.name),
|
||||
.args = primOp.args,
|
||||
.doc = primOp.doc,
|
||||
});
|
||||
}
|
||||
|
||||
/* Add a wrapper around the derivation primop that computes the
|
||||
`drvPath' and `outPath' attributes lazily. */
|
||||
|
|
|
@ -16,6 +16,7 @@ struct RegisterPrimOp
|
|||
size_t arity = 0;
|
||||
const char * doc;
|
||||
PrimOpFun fun;
|
||||
std::optional<ExperimentalFeature> experimentalFeature;
|
||||
};
|
||||
|
||||
typedef std::vector<Info> PrimOps;
|
||||
|
@ -35,6 +36,7 @@ struct RegisterPrimOp
|
|||
/* These primops are disabled without enableNativeCode, but plugins
|
||||
may wish to use them in limited contexts without globally enabling
|
||||
them. */
|
||||
|
||||
/* Load a ValueInitializer from a DSO and return whatever it initializes */
|
||||
void prim_importNative(EvalState & state, const Pos & pos, Value * * args, Value & v);
|
||||
|
||||
|
|
|
@ -7,8 +7,6 @@ namespace nix {
|
|||
|
||||
static void prim_fetchClosure(EvalState & state, const Pos & pos, Value * * args, Value & v)
|
||||
{
|
||||
settings.requireExperimentalFeature(Xp::FetchClosure);
|
||||
|
||||
state.forceAttrs(*args[0], pos);
|
||||
|
||||
std::optional<std::string> fromStoreUrl;
|
||||
|
@ -145,8 +143,12 @@ static RegisterPrimOp primop_fetchClosure({
|
|||
specifying a binary cache from which the path can be fetched.
|
||||
Also, requiring a content-addressed final store path avoids the
|
||||
need for users to configure binary cache public keys.
|
||||
|
||||
This function is only available if you enable the experimental
|
||||
feature `fetch-closure`.
|
||||
)",
|
||||
.fun = prim_fetchClosure,
|
||||
.experimentalFeature = Xp::FetchClosure,
|
||||
});
|
||||
|
||||
}
|
||||
|
|
|
@ -289,6 +289,7 @@ void mainWrapped(int argc, char * * argv)
|
|||
}
|
||||
|
||||
if (argc == 2 && std::string(argv[1]) == "__dump-builtins") {
|
||||
settings.experimentalFeatures = {Xp::Flakes, Xp::FetchClosure};
|
||||
evalSettings.pureEval = false;
|
||||
EvalState state({}, openStore("dummy://"));
|
||||
auto res = nlohmann::json::object();
|
||||
|
|
Loading…
Reference in a new issue