aboutsummaryrefslogtreecommitdiff
path: root/src/libexpr/flake
diff options
context:
space:
mode:
authorGuillaume Maudoux <guillaume.maudoux@tweag.io>2022-09-07 00:34:03 +0200
committerGuillaume Maudoux <guillaume.maudoux@tweag.io>2022-09-07 00:34:03 +0200
commiteb460a9529dd79995b6b788d59322fbc8f989214 (patch)
tree2dec54ef6b3096d787cb49cb0f2f6b7041b1f6c1 /src/libexpr/flake
parent9ff892aad4ee13532ea84cb6e4a2a53d70945efe (diff)
parent96001098796c9011d1670cc8a7acd00ef49b2d7a (diff)
WIP: broken merge but need a git checkpoint
Diffstat (limited to 'src/libexpr/flake')
-rw-r--r--src/libexpr/flake/config.cc13
-rw-r--r--src/libexpr/flake/flake.cc35
-rw-r--r--src/libexpr/flake/flakeref.cc17
-rw-r--r--src/libexpr/flake/flakeref.hh10
4 files changed, 52 insertions, 23 deletions
diff --git a/src/libexpr/flake/config.cc b/src/libexpr/flake/config.cc
index a811e59a1..3e9d264b4 100644
--- a/src/libexpr/flake/config.cc
+++ b/src/libexpr/flake/config.cc
@@ -31,7 +31,7 @@ static void writeTrustedList(const TrustedList & trustedList)
void ConfigFile::apply()
{
- std::set<std::string> whitelist{"bash-prompt", "bash-prompt-suffix", "flake-registry"};
+ std::set<std::string> whitelist{"bash-prompt", "bash-prompt-prefix", "bash-prompt-suffix", "flake-registry"};
for (auto & [name, value] : settings) {
@@ -50,13 +50,11 @@ void ConfigFile::apply()
else
assert(false);
- if (!whitelist.count(baseName)) {
- auto trustedList = readTrustedList();
-
+ if (!whitelist.count(baseName) && !nix::fetchSettings.acceptFlakeConfig) {
bool trusted = false;
- if (nix::fetchSettings.acceptFlakeConfig){
- trusted = true;
- } else if (auto saved = get(get(trustedList, name).value_or(std::map<std::string, bool>()), valueS)) {
+ auto trustedList = readTrustedList();
+ auto tlname = get(trustedList, name);
+ if (auto saved = tlname ? get(*tlname, valueS) : nullptr) {
trusted = *saved;
warn("Using saved setting for '%s = %s' from ~/.local/share/nix/trusted-settings.json.", name,valueS);
} else {
@@ -69,7 +67,6 @@ void ConfigFile::apply()
writeTrustedList(trustedList);
}
}
-
if (!trusted) {
warn("ignoring untrusted flake configuration setting '%s'", name);
continue;
diff --git a/src/libexpr/flake/flake.cc b/src/libexpr/flake/flake.cc
index 29fd51dd1..06562f614 100644
--- a/src/libexpr/flake/flake.cc
+++ b/src/libexpr/flake/flake.cc
@@ -341,7 +341,6 @@ LockedFlake lockFlake(
debug("old lock file: %s", oldLockFile);
- // FIXME: check whether all overrides are used.
std::map<InputPath, FlakeInput> overrides;
std::set<InputPath> overridesUsed, updatesUsed;
@@ -384,6 +383,18 @@ LockedFlake lockFlake(
}
}
+ /* Check whether this input has overrides for a
+ non-existent input. */
+ for (auto [inputPath, inputOverride] : overrides) {
+ auto inputPath2(inputPath);
+ auto follow = inputPath2.back();
+ inputPath2.pop_back();
+ if (inputPath2 == inputPathPrefix && !flakeInputs.count(follow))
+ warn(
+ "input '%s' has an override for a non-existent input '%s'",
+ printInputPath(inputPathPrefix), follow);
+ }
+
/* Go over the flake inputs, resolve/fetch them if
necessary (i.e. if they're new or the flakeref changed
from what's in the lock file). */
@@ -513,6 +524,15 @@ LockedFlake lockFlake(
if (!lockFlags.allowMutable && !input.ref->input.isLocked())
throw Error("cannot update flake input '%s' in pure mode", inputPathS);
+ /* Note: in case of an --override-input, we use
+ the *original* ref (input2.ref) for the
+ "original" field, rather than the
+ override. This ensures that the override isn't
+ nuked the next time we update the lock
+ file. That is, overrides are sticky unless you
+ use --no-write-lock-file. */
+ auto ref = input2.ref ? *input2.ref : *input.ref;
+
if (input.isFlake) {
Path localPath = parentPath;
FlakeRef localRef = *input.ref;
@@ -524,15 +544,7 @@ LockedFlake lockFlake(
auto inputFlake = getFlake(state, localRef, useRegistries, flakeCache, inputPath);
- /* Note: in case of an --override-input, we use
- the *original* ref (input2.ref) for the
- "original" field, rather than the
- override. This ensures that the override isn't
- nuked the next time we update the lock
- file. That is, overrides are sticky unless you
- use --no-write-lock-file. */
- auto childNode = std::make_shared<LockedNode>(
- inputFlake.lockedRef, input2.ref ? *input2.ref : *input.ref);
+ auto childNode = std::make_shared<LockedNode>(inputFlake.lockedRef, ref);
node->inputs.insert_or_assign(id, childNode);
@@ -560,7 +572,7 @@ LockedFlake lockFlake(
auto [sourceInfo, resolvedRef, lockedRef] = fetchOrSubstituteTree(
state, *input.ref, useRegistries, flakeCache);
node->inputs.insert_or_assign(id,
- std::make_shared<LockedNode>(lockedRef, *input.ref, false));
+ std::make_shared<LockedNode>(lockedRef, ref, false));
}
}
@@ -723,6 +735,7 @@ static void prim_getFlake(EvalState & state, const PosIdx pos, Value * * args, V
lockFlake(state, flakeRef,
LockFlags {
.updateLockFile = false,
+ .writeLockFile = false,
.useRegistries = !evalSettings.pureEval && fetchSettings.useRegistries,
.allowMutable = !evalSettings.pureEval,
}),
diff --git a/src/libexpr/flake/flakeref.cc b/src/libexpr/flake/flakeref.cc
index c1eae413f..eede493f8 100644
--- a/src/libexpr/flake/flakeref.cc
+++ b/src/libexpr/flake/flakeref.cc
@@ -176,7 +176,7 @@ std::pair<FlakeRef, std::string> parseFlakeRefWithFragment(
parsedURL.query.insert_or_assign("shallow", "1");
return std::make_pair(
- FlakeRef(Input::fromURL(parsedURL), get(parsedURL.query, "dir").value_or("")),
+ FlakeRef(Input::fromURL(parsedURL), getOr(parsedURL.query, "dir", "")),
fragment);
}
@@ -189,7 +189,7 @@ std::pair<FlakeRef, std::string> parseFlakeRefWithFragment(
if (!hasPrefix(path, "/"))
throw BadURL("flake reference '%s' is not an absolute path", url);
auto query = decodeQuery(match[2]);
- path = canonPath(path + "/" + get(query, "dir").value_or(""));
+ path = canonPath(path + "/" + getOr(query, "dir", ""));
}
fetchers::Attrs attrs;
@@ -208,7 +208,7 @@ std::pair<FlakeRef, std::string> parseFlakeRefWithFragment(
input.parent = baseDir;
return std::make_pair(
- FlakeRef(std::move(input), get(parsedURL.query, "dir").value_or("")),
+ FlakeRef(std::move(input), getOr(parsedURL.query, "dir", "")),
fragment);
}
}
@@ -238,4 +238,15 @@ std::pair<fetchers::Tree, FlakeRef> FlakeRef::fetchTree(ref<Store> store) const
return {std::move(tree), FlakeRef(std::move(lockedInput), subdir)};
}
+std::tuple<FlakeRef, std::string, OutputsSpec> parseFlakeRefWithFragmentAndOutputsSpec(
+ const std::string & url,
+ const std::optional<Path> & baseDir,
+ bool allowMissing,
+ bool isFlake)
+{
+ auto [prefix, outputsSpec] = parseOutputsSpec(url);
+ auto [flakeRef, fragment] = parseFlakeRefWithFragment(prefix, baseDir, allowMissing, isFlake);
+ return {std::move(flakeRef), fragment, outputsSpec};
+}
+
}
diff --git a/src/libexpr/flake/flakeref.hh b/src/libexpr/flake/flakeref.hh
index 1fddfd9a0..fe4f67193 100644
--- a/src/libexpr/flake/flakeref.hh
+++ b/src/libexpr/flake/flakeref.hh
@@ -3,6 +3,7 @@
#include "types.hh"
#include "hash.hh"
#include "fetchers.hh"
+#include "path-with-outputs.hh"
#include <variant>
@@ -27,7 +28,7 @@ typedef std::string FlakeId;
* object that fetcher generates (usually via
* FlakeRef::fromAttrs(attrs) or parseFlakeRef(url) calls).
*
- * The actual fetch not have been performed yet (i.e. a FlakeRef may
+ * The actual fetch may not have been performed yet (i.e. a FlakeRef may
* be lazy), but the fetcher can be invoked at any time via the
* FlakeRef to ensure the store is populated with this input.
*/
@@ -79,4 +80,11 @@ std::pair<FlakeRef, std::string> parseFlakeRefWithFragment(
std::optional<std::pair<FlakeRef, std::string>> maybeParseFlakeRefWithFragment(
const std::string & url, const std::optional<Path> & baseDir = {});
+std::tuple<FlakeRef, std::string, OutputsSpec> parseFlakeRefWithFragmentAndOutputsSpec(
+ const std::string & url,
+ const std::optional<Path> & baseDir = {},
+ bool allowMissing = false,
+ bool isFlake = true);
+
+
}