Restore subdir support in registries
Hacky...
This commit is contained in:
parent
890df325c7
commit
d068f9ffff
6 changed files with 60 additions and 31 deletions
|
@ -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);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -29,17 +29,26 @@ 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
|
||||
throw Error("flake registry '%s' has unsupported version %d", path, version);
|
||||
|
@ -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};
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue