1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2025-06-25 14:51:16 +02:00

nix-flake: Move primops registration to configureEvalSettings

This commit is contained in:
Robert Hensing 2025-03-26 09:32:26 +00:00
parent 6a192ec0cd
commit d48101109d
4 changed files with 106 additions and 106 deletions

View file

@ -56,4 +56,105 @@ PrimOp getFlake(const Settings & settings)
};
}
static void prim_parseFlakeRef(EvalState & state, const PosIdx pos, Value ** args, Value & v)
{
std::string flakeRefS(
state.forceStringNoCtx(*args[0], pos, "while evaluating the argument passed to builtins.parseFlakeRef"));
auto attrs = nix::parseFlakeRef(state.fetchSettings, flakeRefS, {}, true).toAttrs();
auto binds = state.buildBindings(attrs.size());
for (const auto & [key, value] : attrs) {
auto s = state.symbols.create(key);
auto & vv = binds.alloc(s);
std::visit(
overloaded{
[&vv](const std::string & value) { vv.mkString(value); },
[&vv](const uint64_t & value) { vv.mkInt(value); },
[&vv](const Explicit<bool> & value) { vv.mkBool(value.t); }},
value);
}
v.mkAttrs(binds);
}
nix::PrimOp parseFlakeRef({
.name = "__parseFlakeRef",
.args = {"flake-ref"},
.doc = R"(
Parse a flake reference, and return its exploded form.
For example:
```nix
builtins.parseFlakeRef "github:NixOS/nixpkgs/23.05?dir=lib"
```
evaluates to:
```nix
{ dir = "lib"; owner = "NixOS"; ref = "23.05"; repo = "nixpkgs"; type = "github"; }
```
)",
.fun = prim_parseFlakeRef,
.experimentalFeature = Xp::Flakes,
});
static void prim_flakeRefToString(EvalState & state, const PosIdx pos, Value ** args, Value & v)
{
state.forceAttrs(*args[0], noPos, "while evaluating the argument passed to builtins.flakeRefToString");
fetchers::Attrs attrs;
for (const auto & attr : *args[0]->attrs()) {
auto t = attr.value->type();
if (t == nInt) {
auto intValue = attr.value->integer().value;
if (intValue < 0) {
state
.error<EvalError>(
"negative value given for flake ref attr %1%: %2%", state.symbols[attr.name], intValue)
.atPos(pos)
.debugThrow();
}
attrs.emplace(state.symbols[attr.name], uint64_t(intValue));
} else if (t == nBool) {
attrs.emplace(state.symbols[attr.name], Explicit<bool>{attr.value->boolean()});
} else if (t == nString) {
attrs.emplace(state.symbols[attr.name], std::string(attr.value->string_view()));
} else {
state
.error<EvalError>(
"flake reference attribute sets may only contain integers, Booleans, "
"and strings, but attribute '%s' is %s",
state.symbols[attr.name],
showType(*attr.value))
.debugThrow();
}
}
auto flakeRef = FlakeRef::fromAttrs(state.fetchSettings, attrs);
v.mkString(flakeRef.to_string());
}
nix::PrimOp flakeRefToString({
.name = "__flakeRefToString",
.args = {"attrs"},
.doc = R"(
Convert a flake reference from attribute set format to URL format.
For example:
```nix
builtins.flakeRefToString {
dir = "lib"; owner = "NixOS"; ref = "23.05"; repo = "nixpkgs"; type = "github";
}
```
evaluates to
```nix
"github:NixOS/nixpkgs/23.05?dir=lib"
```
)",
.fun = prim_flakeRefToString,
.experimentalFeature = Xp::Flakes,
});
} // namespace nix::flake::primops

View file

@ -10,4 +10,7 @@ namespace nix::flake::primops {
*/
nix::PrimOp getFlake(const Settings & settings);
extern nix::PrimOp parseFlakeRef;
extern nix::PrimOp flakeRefToString;
} // namespace nix::flake

View file

@ -973,112 +973,6 @@ void callFlake(EvalState & state,
state.callFunction(*vCallFlake, args, vRes, noPos);
}
static void prim_parseFlakeRef(
EvalState & state,
const PosIdx pos,
Value * * args,
Value & v)
{
std::string flakeRefS(state.forceStringNoCtx(*args[0], pos,
"while evaluating the argument passed to builtins.parseFlakeRef"));
auto attrs = parseFlakeRef(state.fetchSettings, flakeRefS, {}, true).toAttrs();
auto binds = state.buildBindings(attrs.size());
for (const auto & [key, value] : attrs) {
auto s = state.symbols.create(key);
auto & vv = binds.alloc(s);
std::visit(overloaded {
[&vv](const std::string & value) { vv.mkString(value); },
[&vv](const uint64_t & value) { vv.mkInt(value); },
[&vv](const Explicit<bool> & value) { vv.mkBool(value.t); }
}, value);
}
v.mkAttrs(binds);
}
static RegisterPrimOp r3({
.name = "__parseFlakeRef",
.args = {"flake-ref"},
.doc = R"(
Parse a flake reference, and return its exploded form.
For example:
```nix
builtins.parseFlakeRef "github:NixOS/nixpkgs/23.05?dir=lib"
```
evaluates to:
```nix
{ dir = "lib"; owner = "NixOS"; ref = "23.05"; repo = "nixpkgs"; type = "github"; }
```
)",
.fun = prim_parseFlakeRef,
.experimentalFeature = Xp::Flakes,
});
static void prim_flakeRefToString(
EvalState & state,
const PosIdx pos,
Value * * args,
Value & v)
{
state.forceAttrs(*args[0], noPos,
"while evaluating the argument passed to builtins.flakeRefToString");
fetchers::Attrs attrs;
for (const auto & attr : *args[0]->attrs()) {
auto t = attr.value->type();
if (t == nInt) {
auto intValue = attr.value->integer().value;
if (intValue < 0) {
state.error<EvalError>("negative value given for flake ref attr %1%: %2%", state.symbols[attr.name], intValue).atPos(pos).debugThrow();
}
attrs.emplace(state.symbols[attr.name], uint64_t(intValue));
} else if (t == nBool) {
attrs.emplace(state.symbols[attr.name],
Explicit<bool> { attr.value->boolean() });
} else if (t == nString) {
attrs.emplace(state.symbols[attr.name],
std::string(attr.value->string_view()));
} else {
state.error<EvalError>(
"flake reference attribute sets may only contain integers, Booleans, "
"and strings, but attribute '%s' is %s",
state.symbols[attr.name],
showType(*attr.value)).debugThrow();
}
}
auto flakeRef = FlakeRef::fromAttrs(state.fetchSettings, attrs);
v.mkString(flakeRef.to_string());
}
static RegisterPrimOp r4({
.name = "__flakeRefToString",
.args = {"attrs"},
.doc = R"(
Convert a flake reference from attribute set format to URL format.
For example:
```nix
builtins.flakeRefToString {
dir = "lib"; owner = "NixOS"; ref = "23.05"; repo = "nixpkgs"; type = "github";
}
```
evaluates to
```nix
"github:NixOS/nixpkgs/23.05?dir=lib"
```
)",
.fun = prim_flakeRefToString,
.experimentalFeature = Xp::Flakes,
});
}
std::optional<Fingerprint> LockedFlake::getFingerprint(

View file

@ -8,6 +8,8 @@ Settings::Settings() {}
void Settings::configureEvalSettings(nix::EvalSettings & evalSettings)
{
evalSettings.addPrimOp(primops::getFlake(*this));
evalSettings.addPrimOp(primops::parseFlakeRef);
evalSettings.addPrimOp(primops::flakeRefToString);
}
} // namespace nix