aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2020-02-20 22:14:44 +0100
committerEelco Dolstra <edolstra@gmail.com>2020-02-20 22:14:44 +0100
commitd068f9ffff3d2a98e6dde0834a250e4930d44778 (patch)
treeea9359e05ea924fb32fe11c190bdefd13437d4b4 /src
parent890df325c76a9acd90300bb3590e7d1b102e2c28 (diff)
Restore subdir support in registries
Hacky...
Diffstat (limited to 'src')
-rw-r--r--src/libexpr/common-eval-args.cc8
-rw-r--r--src/libexpr/flake/flakeref.cc3
-rw-r--r--src/libexpr/primops/fetchTree.cc2
-rw-r--r--src/libstore/fetchers/registry.cc47
-rw-r--r--src/libstore/fetchers/registry.hh19
-rw-r--r--src/nix/flake.cc12
6 files changed, 60 insertions, 31 deletions
diff --git a/src/libexpr/common-eval-args.cc b/src/libexpr/common-eval-args.cc
index e3135b472..1fdd4e9ec 100644
--- a/src/libexpr/common-eval-args.cc
+++ b/src/libexpr/common-eval-args.cc
@@ -42,9 +42,11 @@ MixEvalArgs::MixEvalArgs()
.description("override a flake registry value")
.arity(2)
.handler([&](std::vector<std::string> ss) {
- fetchers::overrideRegistry(
- parseFlakeRef(ss[0], absPath(".")).input,
- parseFlakeRef(ss[1], absPath(".")).input);
+ auto from = parseFlakeRef(ss[0], absPath("."));
+ auto to = parseFlakeRef(ss[1], absPath("."));
+ fetchers::Input::Attrs extraAttrs;
+ if (to.subdir != "") extraAttrs["subdir"] = to.subdir;
+ fetchers::overrideRegistry(from.input, to.input, extraAttrs);
});
}
diff --git a/src/libexpr/flake/flakeref.cc b/src/libexpr/flake/flakeref.cc
index c46661df8..b61352749 100644
--- a/src/libexpr/flake/flakeref.cc
+++ b/src/libexpr/flake/flakeref.cc
@@ -40,7 +40,8 @@ bool FlakeRef::operator ==(const FlakeRef & other) const
FlakeRef FlakeRef::resolve(ref<Store> store) const
{
- return FlakeRef(lookupInRegistries(store, input), subdir);
+ auto [input2, extraAttrs] = lookupInRegistries(store, input);
+ return FlakeRef(input2, fetchers::maybeGetStrAttr(extraAttrs, "subdir").value_or(subdir));
}
FlakeRef parseFlakeRef(
diff --git a/src/libexpr/primops/fetchTree.cc b/src/libexpr/primops/fetchTree.cc
index 8fa1f1a11..60bd2ed11 100644
--- a/src/libexpr/primops/fetchTree.cc
+++ b/src/libexpr/primops/fetchTree.cc
@@ -36,7 +36,7 @@ static void prim_fetchTree(EvalState & state, const Pos & pos, Value * * args, V
input = fetchers::inputFromURL(state.coerceToString(pos, *args[0], context, false, false));
if (!evalSettings.pureEval && !input->isDirect())
- input = lookupInRegistries(state.store, input);
+ input = lookupInRegistries(state.store, input).first;
if (evalSettings.pureEval && !input->isImmutable())
throw Error("in pure evaluation mode, 'fetchTree' requires an immutable input");
diff --git a/src/libstore/fetchers/registry.cc b/src/libstore/fetchers/registry.cc
index 1fd42a169..ebf326bcc 100644
--- a/src/libstore/fetchers/registry.cc
+++ b/src/libstore/fetchers/registry.cc
@@ -29,16 +29,25 @@ std::shared_ptr<Registry> Registry::read(
throw Error("flake registry '%s' lacks a 'url' attribute for entry '%s'",
path, i.key());
registry->entries.push_back(
- {inputFromURL(i.key()), inputFromURL(url)});
+ {inputFromURL(i.key()), inputFromURL(url), {}});
}
}
else if (version == 2) {
- for (auto & i : json["flakes"])
+ for (auto & i : json["flakes"]) {
+ auto toAttrs = jsonToAttrs(i["to"]);
+ Input::Attrs extraAttrs;
+ auto j = toAttrs.find("subdir");
+ if (j != toAttrs.end()) {
+ extraAttrs.insert(*j);
+ toAttrs.erase(j);
+ }
registry->entries.push_back(
{ inputFromAttrs(jsonToAttrs(i["from"]))
- , inputFromAttrs(jsonToAttrs(i["to"]))
+ , inputFromAttrs(toAttrs)
+ , extraAttrs
});
+ }
}
else
@@ -53,8 +62,9 @@ void Registry::write(const Path & path)
nlohmann::json arr;
for (auto & elem : entries) {
nlohmann::json obj;
- obj["from"] = attrsToJson(elem.first->toAttrs());
- obj["to"] = attrsToJson(elem.second->toAttrs());
+ obj["from"] = attrsToJson(std::get<0>(elem)->toAttrs());
+ obj["to"] = attrsToJson(std::get<1>(elem)->toAttrs());
+ obj["to"].update(attrsToJson(std::get<2>(elem)));
arr.emplace_back(std::move(obj));
}
@@ -68,16 +78,17 @@ void Registry::write(const Path & path)
void Registry::add(
const std::shared_ptr<const Input> & from,
- const std::shared_ptr<const Input> & to)
+ const std::shared_ptr<const Input> & to,
+ const Input::Attrs & extraAttrs)
{
- entries.emplace_back(from, to);
+ entries.emplace_back(from, to, extraAttrs);
}
void Registry::remove(const std::shared_ptr<const Input> & input)
{
// FIXME: use C++20 std::erase.
for (auto i = entries.begin(); i != entries.end(); )
- if (*i->first == *input)
+ if (*std::get<0>(*i) == *input)
i = entries.erase(i);
else
++i;
@@ -103,9 +114,10 @@ std::shared_ptr<Registry> getFlagRegistry()
void overrideRegistry(
const std::shared_ptr<const Input> & from,
- const std::shared_ptr<const Input> & to)
+ const std::shared_ptr<const Input> & to,
+ const Input::Attrs & extraAttrs)
{
- flagRegistry->add(from, to);
+ flagRegistry->add(from, to, extraAttrs);
}
static std::shared_ptr<Registry> getGlobalRegistry(ref<Store> store)
@@ -135,10 +147,11 @@ Registries getRegistries(ref<Store> store)
return registries;
}
-std::shared_ptr<const Input> lookupInRegistries(
+std::pair<std::shared_ptr<const Input>, Input::Attrs> lookupInRegistries(
ref<Store> store,
std::shared_ptr<const Input> input)
{
+ Input::Attrs extraAttrs;
int n = 0;
restart:
@@ -149,10 +162,12 @@ std::shared_ptr<const Input> lookupInRegistries(
for (auto & registry : getRegistries(store)) {
// FIXME: O(n)
for (auto & entry : registry->entries) {
- if (entry.first->contains(*input)) {
- input = entry.second->applyOverrides(
- !entry.first->getRef() && input->getRef() ? input->getRef() : std::optional<std::string>(),
- !entry.first->getRev() && input->getRev() ? input->getRev() : std::optional<Hash>());
+ auto from = std::get<0>(entry);
+ if (from->contains(*input)) {
+ input = std::get<1>(entry)->applyOverrides(
+ !from->getRef() && input->getRef() ? input->getRef() : std::optional<std::string>(),
+ !from->getRev() && input->getRev() ? input->getRev() : std::optional<Hash>());
+ extraAttrs = std::get<2>(entry);
goto restart;
}
}
@@ -161,7 +176,7 @@ std::shared_ptr<const Input> lookupInRegistries(
if (!input->isDirect())
throw Error("cannot find flake '%s' in the flake registries", input->to_string());
- return input;
+ return {input, extraAttrs};
}
}
diff --git a/src/libstore/fetchers/registry.hh b/src/libstore/fetchers/registry.hh
index e29f78486..6063f51d6 100644
--- a/src/libstore/fetchers/registry.hh
+++ b/src/libstore/fetchers/registry.hh
@@ -1,13 +1,12 @@
#pragma once
#include "types.hh"
+#include "fetchers.hh"
namespace nix { class Store; }
namespace nix::fetchers {
-struct Input;
-
struct Registry
{
enum RegistryType {
@@ -18,7 +17,13 @@ struct Registry
RegistryType type;
- std::vector<std::pair<std::shared_ptr<const Input>, std::shared_ptr<const Input>>> entries;
+ std::vector<
+ std::tuple<
+ std::shared_ptr<const Input>, // from
+ std::shared_ptr<const Input>, // to
+ Input::Attrs // extra attributes
+ >
+ > entries;
Registry(RegistryType type)
: type(type)
@@ -31,7 +36,8 @@ struct Registry
void add(
const std::shared_ptr<const Input> & from,
- const std::shared_ptr<const Input> & to);
+ const std::shared_ptr<const Input> & to,
+ const Input::Attrs & extraAttrs);
void remove(const std::shared_ptr<const Input> & input);
};
@@ -46,9 +52,10 @@ Registries getRegistries(ref<Store> store);
void overrideRegistry(
const std::shared_ptr<const Input> & from,
- const std::shared_ptr<const Input> & to);
+ const std::shared_ptr<const Input> & to,
+ const Input::Attrs & extraAttrs);
-std::shared_ptr<const Input> lookupInRegistries(
+std::pair<std::shared_ptr<const Input>, Input::Attrs> lookupInRegistries(
ref<Store> store,
std::shared_ptr<const Input> input);
diff --git a/src/nix/flake.cc b/src/nix/flake.cc
index 9c94c59fc..42f5b2ce0 100644
--- a/src/nix/flake.cc
+++ b/src/nix/flake.cc
@@ -70,8 +70,8 @@ struct CmdFlakeList : EvalCommand
registry->type == Registry::Flag ? "flags " :
registry->type == Registry::User ? "user " :
"global",
- entry.first->to_string(),
- entry.second->to_string());
+ std::get<0>(entry)->to_string(),
+ std::get<1>(entry)->to_string());
}
}
}
@@ -506,9 +506,11 @@ struct CmdFlakeAdd : MixEvalArgs, Command
{
auto fromRef = parseFlakeRef(fromUrl);
auto toRef = parseFlakeRef(toUrl);
+ fetchers::Input::Attrs extraAttrs;
+ if (toRef.subdir != "") extraAttrs["subdir"] = toRef.subdir;
auto userRegistry = fetchers::getUserRegistry();
userRegistry->remove(fromRef.input);
- userRegistry->add(fromRef.input, toRef.input);
+ userRegistry->add(fromRef.input, toRef.input, extraAttrs);
userRegistry->write(fetchers::getUserRegistryPath());
}
};
@@ -555,7 +557,9 @@ struct CmdFlakePin : virtual Args, EvalCommand
auto userRegistry = fetchers::getUserRegistry();
userRegistry->remove(ref.input);
auto [tree, resolved] = ref.resolve(store).input->fetchTree(store);
- userRegistry->add(ref.input, resolved);
+ fetchers::Input::Attrs extraAttrs;
+ if (ref.subdir != "") extraAttrs["subdir"] = ref.subdir;
+ userRegistry->add(ref.input, resolved, extraAttrs);
}
};