Support registry entries that must match exactly

An example use is for pinning the "nixpkgs" entry the system-wide
registry to a particular store path. Inexact matches
(e.g. "nixpkgs/master") should still use the global registry.
This commit is contained in:
Eelco Dolstra 2020-04-01 23:12:45 +02:00
parent bd10a07d17
commit 74024515a3
2 changed files with 19 additions and 6 deletions

View file

@ -43,11 +43,13 @@ std::shared_ptr<Registry> Registry::read(
extraAttrs.insert(*j); extraAttrs.insert(*j);
toAttrs.erase(j); toAttrs.erase(j);
} }
auto exact = i.find("exact");
registry->entries.push_back( registry->entries.push_back(
Entry { Entry {
.from = inputFromAttrs(jsonToAttrs(i["from"])), .from = inputFromAttrs(jsonToAttrs(i["from"])),
.to = inputFromAttrs(toAttrs), .to = inputFromAttrs(toAttrs),
.extraAttrs = extraAttrs, .extraAttrs = extraAttrs,
.exact = exact != i.end() && exact.value()
}); });
} }
} }
@ -68,6 +70,8 @@ void Registry::write(const Path & path)
obj["to"] = attrsToJson(entry.to->toAttrs()); obj["to"] = attrsToJson(entry.to->toAttrs());
if (!entry.extraAttrs.empty()) if (!entry.extraAttrs.empty())
obj["to"].update(attrsToJson(entry.extraAttrs)); obj["to"].update(attrsToJson(entry.extraAttrs));
if (entry.exact)
obj["exact"] = true;
arr.emplace_back(std::move(obj)); arr.emplace_back(std::move(obj));
} }
@ -185,12 +189,20 @@ std::pair<std::shared_ptr<const Input>, Attrs> lookupInRegistries(
for (auto & registry : getRegistries(store)) { for (auto & registry : getRegistries(store)) {
// FIXME: O(n) // FIXME: O(n)
for (auto & entry : registry->entries) { for (auto & entry : registry->entries) {
if (entry.from->contains(*input)) { if (entry.exact) {
input = entry.to->applyOverrides( if (*entry.from == *input) {
!entry.from->getRef() && input->getRef() ? input->getRef() : std::optional<std::string>(), input = entry.to;
!entry.from->getRev() && input->getRev() ? input->getRev() : std::optional<Hash>()); extraAttrs = entry.extraAttrs;
extraAttrs = entry.extraAttrs; goto restart;
goto restart; }
} else {
if (entry.from->contains(*input)) {
input = entry.to->applyOverrides(
!entry.from->getRef() && input->getRef() ? input->getRef() : std::optional<std::string>(),
!entry.from->getRev() && input->getRev() ? input->getRev() : std::optional<Hash>());
extraAttrs = entry.extraAttrs;
goto restart;
}
} }
} }
} }

View file

@ -23,6 +23,7 @@ struct Registry
std::shared_ptr<const Input> from; std::shared_ptr<const Input> from;
std::shared_ptr<const Input> to; std::shared_ptr<const Input> to;
Attrs extraAttrs; Attrs extraAttrs;
bool exact = false;
}; };
std::vector<Entry> entries; std::vector<Entry> entries;