aboutsummaryrefslogtreecommitdiff
path: root/src/libexpr
diff options
context:
space:
mode:
Diffstat (limited to 'src/libexpr')
-rw-r--r--src/libexpr/flake/flake.cc17
-rw-r--r--src/libexpr/flake/flake.hh1
-rw-r--r--src/libexpr/flake/flakeref.cc9
-rw-r--r--src/libexpr/parser.y3
-rw-r--r--src/libexpr/primops.cc4
5 files changed, 18 insertions, 16 deletions
diff --git a/src/libexpr/flake/flake.cc b/src/libexpr/flake/flake.cc
index 01f464859..b4ede542c 100644
--- a/src/libexpr/flake/flake.cc
+++ b/src/libexpr/flake/flake.cc
@@ -48,17 +48,17 @@ static std::tuple<fetchers::Tree, FlakeRef, FlakeRef> fetchOrSubstituteTree(
resolvedRef = originalRef.resolve(state.store);
auto fetchedResolved = lookupInFlakeCache(flakeCache, originalRef);
if (!fetchedResolved) fetchedResolved.emplace(resolvedRef.fetchTree(state.store));
- flakeCache.push_back({resolvedRef, fetchedResolved.value()});
- fetched.emplace(fetchedResolved.value());
+ flakeCache.push_back({resolvedRef, *fetchedResolved});
+ fetched.emplace(*fetchedResolved);
}
else {
throw Error("'%s' is an indirect flake reference, but registry lookups are not allowed", originalRef);
}
}
- flakeCache.push_back({originalRef, fetched.value()});
+ flakeCache.push_back({originalRef, *fetched});
}
- auto [tree, lockedRef] = fetched.value();
+ auto [tree, lockedRef] = *fetched;
debug("got tree '%s' from '%s'",
state.store->printStorePath(tree.storePath), lockedRef);
@@ -215,10 +215,9 @@ static Flake getFlake(
if (auto outputs = vInfo.attrs->get(sOutputs)) {
expectType(state, tLambda, *outputs->value, *outputs->pos);
- flake.vOutputs = allocRootValue(outputs->value);
- if ((*flake.vOutputs)->lambda.fun->matchAttrs) {
- for (auto & formal : (*flake.vOutputs)->lambda.fun->formals->formals) {
+ if (outputs->value->lambda.fun->matchAttrs) {
+ for (auto & formal : outputs->value->lambda.fun->formals->formals) {
if (formal.name != state.sSelf)
flake.inputs.emplace(formal.name, FlakeInput {
.ref = parseFlakeRef(formal.name)
@@ -248,7 +247,7 @@ Flake getFlake(EvalState & state, const FlakeRef & originalRef, bool allowLookup
}
/* Compute an in-memory lock file for the specified top-level flake,
- and optionally write it to file, it the flake is writable. */
+ and optionally write it to file, if the flake is writable. */
LockedFlake lockFlake(
EvalState & state,
const FlakeRef & topRef,
@@ -367,7 +366,7 @@ LockedFlake lockFlake(
/* If we have an --update-input flag for an input
of this input, then we must fetch the flake to
- to update it. */
+ update it. */
auto lb = lockFlags.inputUpdates.lower_bound(inputPath);
auto hasChildUpdate =
diff --git a/src/libexpr/flake/flake.hh b/src/libexpr/flake/flake.hh
index c2bb2888b..69c779af8 100644
--- a/src/libexpr/flake/flake.hh
+++ b/src/libexpr/flake/flake.hh
@@ -34,7 +34,6 @@ struct Flake
std::optional<std::string> description;
std::shared_ptr<const fetchers::Tree> sourceInfo;
FlakeInputs inputs;
- RootValue vOutputs;
~Flake();
};
diff --git a/src/libexpr/flake/flakeref.cc b/src/libexpr/flake/flakeref.cc
index d5c2ffe66..833e8a776 100644
--- a/src/libexpr/flake/flakeref.cc
+++ b/src/libexpr/flake/flakeref.cc
@@ -16,10 +16,10 @@ const static std::string subDirRegex = subDirElemRegex + "(?:/" + subDirElemRege
std::string FlakeRef::to_string() const
{
- auto url = input.toURL();
+ std::map<std::string, std::string> extraQuery;
if (subdir != "")
- url.query.insert_or_assign("dir", subdir);
- return url.to_string();
+ extraQuery.insert_or_assign("dir", subdir);
+ return input.toURLString(extraQuery);
}
fetchers::Attrs FlakeRef::toAttrs() const
@@ -157,7 +157,8 @@ std::pair<FlakeRef, std::string> parseFlakeRefWithFragment(
} else {
if (!hasPrefix(path, "/"))
throw BadURL("flake reference '%s' is not an absolute path", url);
- path = canonPath(path);
+ auto query = decodeQuery(match[2]);
+ path = canonPath(path + "/" + get(query, "dir").value_or(""));
}
fetchers::Attrs attrs;
diff --git a/src/libexpr/parser.y b/src/libexpr/parser.y
index 24b21f7da..a4c84c526 100644
--- a/src/libexpr/parser.y
+++ b/src/libexpr/parser.y
@@ -614,8 +614,7 @@ Path resolveExprPath(Path path)
// Basic cycle/depth limit to avoid infinite loops.
if (++followCount >= maxFollow)
throw Error("too many symbolic links encountered while traversing the path '%s'", path);
- if (lstat(path.c_str(), &st))
- throw SysError("getting status of '%s'", path);
+ st = lstat(path);
if (!S_ISLNK(st.st_mode)) break;
path = absPath(readLink(path), dirOf(path));
}
diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc
index 9cfe3f402..2b304aab0 100644
--- a/src/libexpr/primops.cc
+++ b/src/libexpr/primops.cc
@@ -2236,6 +2236,10 @@ static RegisterPrimOp primop_catAttrs({
static void prim_functionArgs(EvalState & state, const Pos & pos, Value * * args, Value & v)
{
state.forceValue(*args[0], pos);
+ if (args[0]->type == tPrimOpApp || args[0]->type == tPrimOp) {
+ state.mkAttrs(v, 0);
+ return;
+ }
if (args[0]->type != tLambda)
throw TypeError({
.hint = hintfmt("'functionArgs' requires a function"),