diff options
author | Ben Burdette <bburdette@protonmail.com> | 2022-04-07 13:42:01 -0600 |
---|---|---|
committer | Ben Burdette <bburdette@protonmail.com> | 2022-04-07 13:42:01 -0600 |
commit | 1a93ac8133381eb692416c4e46b1706faa5cd89f (patch) | |
tree | 9a559f977ad6213c055099f6f2ab6be96f0c551b /src/libexpr/flake | |
parent | d2ec9b4e15718e42720787140d7825dcbfd73249 (diff) | |
parent | 8b1e328d5d0ae7d3a4a8f6012ec065b59674ed4a (diff) |
Merge remote-tracking branch 'upstream/master' into upstream-merge
Diffstat (limited to 'src/libexpr/flake')
-rw-r--r-- | src/libexpr/flake/config.cc | 3 | ||||
-rw-r--r-- | src/libexpr/flake/flake.cc | 48 | ||||
-rw-r--r-- | src/libexpr/flake/flakeref.cc | 6 | ||||
-rw-r--r-- | src/libexpr/flake/lockfile.cc | 4 |
4 files changed, 42 insertions, 19 deletions
diff --git a/src/libexpr/flake/config.cc b/src/libexpr/flake/config.cc index 7ecd61816..a811e59a1 100644 --- a/src/libexpr/flake/config.cc +++ b/src/libexpr/flake/config.cc @@ -1,5 +1,6 @@ #include "flake.hh" #include "globals.hh" +#include "fetch-settings.hh" #include <nlohmann/json.hpp> @@ -53,7 +54,7 @@ void ConfigFile::apply() auto trustedList = readTrustedList(); bool trusted = false; - if (nix::settings.acceptFlakeConfig){ + if (nix::fetchSettings.acceptFlakeConfig){ trusted = true; } else if (auto saved = get(get(trustedList, name).value_or(std::map<std::string, bool>()), valueS)) { trusted = *saved; diff --git a/src/libexpr/flake/flake.cc b/src/libexpr/flake/flake.cc index 9f3b58909..22257c6b3 100644 --- a/src/libexpr/flake/flake.cc +++ b/src/libexpr/flake/flake.cc @@ -6,6 +6,7 @@ #include "store-api.hh" #include "fetchers.hh" #include "finally.hh" +#include "fetch-settings.hh" namespace nix { @@ -254,7 +255,7 @@ static Flake getFlake( for (auto & setting : *nixConfig->value->attrs) { forceTrivialValue(state, *setting.value, *setting.pos); if (setting.value->type() == nString) - flake.config.settings.insert({setting.name, string(state.forceStringNoCtx(*setting.value, *setting.pos))}); + flake.config.settings.insert({setting.name, std::string(state.forceStringNoCtx(*setting.value, *setting.pos))}); else if (setting.value->type() == nPath) { PathSet emptyContext = {}; flake.config.settings.emplace( @@ -315,7 +316,7 @@ LockedFlake lockFlake( FlakeCache flakeCache; - auto useRegistries = lockFlags.useRegistries.value_or(settings.useRegistries); + auto useRegistries = lockFlags.useRegistries.value_or(fetchSettings.useRegistries); auto flake = getFlake(state, topRef, useRegistries, flakeCache); @@ -501,7 +502,7 @@ LockedFlake lockFlake( this input. */ debug("creating new input '%s'", inputPathS); - if (!lockFlags.allowMutable && !input.ref->input.isImmutable()) + if (!lockFlags.allowMutable && !input.ref->input.isLocked()) throw Error("cannot update flake input '%s' in pure mode", inputPathS); if (input.isFlake) { @@ -591,7 +592,7 @@ LockedFlake lockFlake( if (lockFlags.writeLockFile) { if (auto sourcePath = topRef.input.getSourcePath()) { if (!newLockFile.isImmutable()) { - if (settings.warnDirty) + if (fetchSettings.warnDirty) warn("will not write lock file of flake '%s' because it has a mutable input", topRef); } else { if (!lockFlags.updateLockFile) @@ -618,7 +619,7 @@ LockedFlake lockFlake( if (lockFlags.commitLockFile) { std::string cm; - cm = settings.commitLockFileSummary.get(); + cm = fetchSettings.commitLockFileSummary.get(); if (cm == "") { cm = fmt("%s: %s", relPath, lockFileExists ? "Update" : "Add"); @@ -650,7 +651,7 @@ LockedFlake lockFlake( now. Corner case: we could have reverted from a dirty to a clean tree! */ if (flake.lockedRef.input == prevLockedRef.input - && !flake.lockedRef.input.isImmutable()) + && !flake.lockedRef.input.isLocked()) throw Error("'%s' did not change after I updated its 'flake.lock' file; is 'flake.lock' under version control?", flake.originalRef); } } else @@ -705,24 +706,45 @@ void callFlake(EvalState & state, static void prim_getFlake(EvalState & state, const Pos & pos, Value * * args, Value & v) { - state.requireExperimentalFeatureOnEvaluation(Xp::Flakes, "builtins.getFlake", pos); - - string flakeRefS(state.forceStringNoCtx(*args[0], pos)); + std::string flakeRefS(state.forceStringNoCtx(*args[0], pos)); auto flakeRef = parseFlakeRef(flakeRefS, {}, true); - if (evalSettings.pureEval && !flakeRef.input.isImmutable()) - throw Error("cannot call 'getFlake' on mutable flake reference '%s', at %s (use --impure to override)", flakeRefS, pos); + if (evalSettings.pureEval && !flakeRef.input.isLocked()) + throw Error("cannot call 'getFlake' on unlocked flake reference '%s', at %s (use --impure to override)", flakeRefS, pos); callFlake(state, lockFlake(state, flakeRef, LockFlags { .updateLockFile = false, - .useRegistries = !evalSettings.pureEval && settings.useRegistries, + .useRegistries = !evalSettings.pureEval && fetchSettings.useRegistries, .allowMutable = !evalSettings.pureEval, }), v); } -static RegisterPrimOp r2("__getFlake", 1, prim_getFlake); +static RegisterPrimOp r2({ + .name = "__getFlake", + .args = {"args"}, + .doc = R"( + Fetch a flake from a flake reference, and return its output attributes and some metadata. For example: + + ```nix + (builtins.getFlake "nix/55bc52401966fbffa525c574c14f67b00bc4fb3a").packages.x86_64-linux.nix + ``` + + Unless impure evaluation is allowed (`--impure`), the flake reference + must be "locked", e.g. contain a Git revision or content hash. An + example of an unlocked usage is: + + ```nix + (builtins.getFlake "github:edolstra/dwarffs").rev + ``` + + This function is only available if you enable the experimental feature + `flakes`. + )", + .fun = prim_getFlake, + .experimentalFeature = Xp::Flakes, +}); } diff --git a/src/libexpr/flake/flakeref.cc b/src/libexpr/flake/flakeref.cc index 930ed9ccd..c1eae413f 100644 --- a/src/libexpr/flake/flakeref.cc +++ b/src/libexpr/flake/flakeref.cc @@ -98,7 +98,7 @@ std::pair<FlakeRef, std::string> parseFlakeRefWithFragment( if (std::regex_match(url, match, flakeRegex)) { auto parsedURL = ParsedURL{ .url = url, - .base = "flake:" + std::string(match[1]), + .base = "flake:" + match.str(1), .scheme = "flake", .authority = "", .path = match[1], @@ -106,12 +106,12 @@ std::pair<FlakeRef, std::string> parseFlakeRefWithFragment( return std::make_pair( FlakeRef(Input::fromURL(parsedURL), ""), - percentDecode(std::string(match[6]))); + percentDecode(match.str(6))); } else if (std::regex_match(url, match, pathUrlRegex)) { std::string path = match[1]; - std::string fragment = percentDecode(std::string(match[3])); + std::string fragment = percentDecode(match.str(3)); if (baseDir) { /* Check if 'url' is a path (either absolute or relative diff --git a/src/libexpr/flake/lockfile.cc b/src/libexpr/flake/lockfile.cc index fda340789..60b52d578 100644 --- a/src/libexpr/flake/lockfile.cc +++ b/src/libexpr/flake/lockfile.cc @@ -35,7 +35,7 @@ LockedNode::LockedNode(const nlohmann::json & json) , originalRef(getFlakeRef(json, "original", nullptr)) , isFlake(json.find("flake") != json.end() ? (bool) json["flake"] : true) { - if (!lockedRef.input.isImmutable()) + if (!lockedRef.input.isLocked()) throw Error("lockfile contains mutable lock '%s'", fetchers::attrsToJSON(lockedRef.input.toAttrs())); } @@ -220,7 +220,7 @@ bool LockFile::isImmutable() const for (auto & i : nodes) { if (i == root) continue; auto lockedNode = std::dynamic_pointer_cast<const LockedNode>(i); - if (lockedNode && !lockedNode->lockedRef.input.isImmutable()) return false; + if (lockedNode && !lockedNode->lockedRef.input.isLocked()) return false; } return true; |