From d48101109d8058751bfa5cbc13afeec8b7a8a680 Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Wed, 26 Mar 2025 09:32:26 +0000 Subject: [PATCH] nix-flake: Move primops registration to configureEvalSettings --- src/libflake/flake/flake-primops.cc | 101 ++++++++++++++++++++++++++ src/libflake/flake/flake-primops.hh | 3 + src/libflake/flake/flake.cc | 106 ---------------------------- src/libflake/flake/settings.cc | 2 + 4 files changed, 106 insertions(+), 106 deletions(-) diff --git a/src/libflake/flake/flake-primops.cc b/src/libflake/flake/flake-primops.cc index f04887e85..98ebdee5f 100644 --- a/src/libflake/flake/flake-primops.cc +++ b/src/libflake/flake/flake-primops.cc @@ -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 & 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( + "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{attr.value->boolean()}); + } else if (t == nString) { + attrs.emplace(state.symbols[attr.name], std::string(attr.value->string_view())); + } else { + state + .error( + "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 diff --git a/src/libflake/flake/flake-primops.hh b/src/libflake/flake/flake-primops.hh index 662761c4e..203060563 100644 --- a/src/libflake/flake/flake-primops.hh +++ b/src/libflake/flake/flake-primops.hh @@ -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 \ No newline at end of file diff --git a/src/libflake/flake/flake.cc b/src/libflake/flake/flake.cc index 1427b5818..e3f4e4f4b 100644 --- a/src/libflake/flake/flake.cc +++ b/src/libflake/flake/flake.cc @@ -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 & 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("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 { attr.value->boolean() }); - } else if (t == nString) { - attrs.emplace(state.symbols[attr.name], - std::string(attr.value->string_view())); - } else { - state.error( - "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 LockedFlake::getFingerprint( diff --git a/src/libflake/flake/settings.cc b/src/libflake/flake/settings.cc index f5f9f96d0..4ceca38ec 100644 --- a/src/libflake/flake/settings.cc +++ b/src/libflake/flake/settings.cc @@ -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