diff --git a/src/libfetchers/registry.cc b/src/libfetchers/registry.cc index 6627d3725..e452e8497 100644 --- a/src/libfetchers/registry.cc +++ b/src/libfetchers/registry.cc @@ -43,11 +43,13 @@ std::shared_ptr Registry::read( extraAttrs.insert(*j); toAttrs.erase(j); } + auto exact = i.find("exact"); registry->entries.push_back( Entry { .from = inputFromAttrs(jsonToAttrs(i["from"])), .to = inputFromAttrs(toAttrs), .extraAttrs = extraAttrs, + .exact = exact != i.end() && exact.value() }); } } @@ -68,6 +70,8 @@ void Registry::write(const Path & path) obj["to"] = attrsToJson(entry.to->toAttrs()); if (!entry.extraAttrs.empty()) obj["to"].update(attrsToJson(entry.extraAttrs)); + if (entry.exact) + obj["exact"] = true; arr.emplace_back(std::move(obj)); } @@ -185,12 +189,20 @@ std::pair, Attrs> lookupInRegistries( for (auto & registry : getRegistries(store)) { // FIXME: O(n) for (auto & entry : registry->entries) { - if (entry.from->contains(*input)) { - input = entry.to->applyOverrides( - !entry.from->getRef() && input->getRef() ? input->getRef() : std::optional(), - !entry.from->getRev() && input->getRev() ? input->getRev() : std::optional()); - extraAttrs = entry.extraAttrs; - goto restart; + if (entry.exact) { + if (*entry.from == *input) { + input = entry.to; + extraAttrs = entry.extraAttrs; + goto restart; + } + } else { + if (entry.from->contains(*input)) { + input = entry.to->applyOverrides( + !entry.from->getRef() && input->getRef() ? input->getRef() : std::optional(), + !entry.from->getRev() && input->getRev() ? input->getRev() : std::optional()); + extraAttrs = entry.extraAttrs; + goto restart; + } } } } diff --git a/src/libfetchers/registry.hh b/src/libfetchers/registry.hh index 722c41b10..c3ce948a8 100644 --- a/src/libfetchers/registry.hh +++ b/src/libfetchers/registry.hh @@ -23,6 +23,7 @@ struct Registry std::shared_ptr from; std::shared_ptr to; Attrs extraAttrs; + bool exact = false; }; std::vector entries;