Restore subdir support in registries
Hacky...
This commit is contained in:
parent
890df325c7
commit
d068f9ffff
|
@ -42,9 +42,11 @@ MixEvalArgs::MixEvalArgs()
|
||||||
.description("override a flake registry value")
|
.description("override a flake registry value")
|
||||||
.arity(2)
|
.arity(2)
|
||||||
.handler([&](std::vector<std::string> ss) {
|
.handler([&](std::vector<std::string> ss) {
|
||||||
fetchers::overrideRegistry(
|
auto from = parseFlakeRef(ss[0], absPath("."));
|
||||||
parseFlakeRef(ss[0], absPath(".")).input,
|
auto to = parseFlakeRef(ss[1], absPath("."));
|
||||||
parseFlakeRef(ss[1], absPath(".")).input);
|
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
|
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(
|
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));
|
input = fetchers::inputFromURL(state.coerceToString(pos, *args[0], context, false, false));
|
||||||
|
|
||||||
if (!evalSettings.pureEval && !input->isDirect())
|
if (!evalSettings.pureEval && !input->isDirect())
|
||||||
input = lookupInRegistries(state.store, input);
|
input = lookupInRegistries(state.store, input).first;
|
||||||
|
|
||||||
if (evalSettings.pureEval && !input->isImmutable())
|
if (evalSettings.pureEval && !input->isImmutable())
|
||||||
throw Error("in pure evaluation mode, 'fetchTree' requires an immutable input");
|
throw Error("in pure evaluation mode, 'fetchTree' requires an immutable input");
|
||||||
|
|
|
@ -29,16 +29,25 @@ std::shared_ptr<Registry> Registry::read(
|
||||||
throw Error("flake registry '%s' lacks a 'url' attribute for entry '%s'",
|
throw Error("flake registry '%s' lacks a 'url' attribute for entry '%s'",
|
||||||
path, i.key());
|
path, i.key());
|
||||||
registry->entries.push_back(
|
registry->entries.push_back(
|
||||||
{inputFromURL(i.key()), inputFromURL(url)});
|
{inputFromURL(i.key()), inputFromURL(url), {}});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (version == 2) {
|
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(
|
registry->entries.push_back(
|
||||||
{ inputFromAttrs(jsonToAttrs(i["from"]))
|
{ inputFromAttrs(jsonToAttrs(i["from"]))
|
||||||
, inputFromAttrs(jsonToAttrs(i["to"]))
|
, inputFromAttrs(toAttrs)
|
||||||
|
, extraAttrs
|
||||||
});
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
|
@ -53,8 +62,9 @@ void Registry::write(const Path & path)
|
||||||
nlohmann::json arr;
|
nlohmann::json arr;
|
||||||
for (auto & elem : entries) {
|
for (auto & elem : entries) {
|
||||||
nlohmann::json obj;
|
nlohmann::json obj;
|
||||||
obj["from"] = attrsToJson(elem.first->toAttrs());
|
obj["from"] = attrsToJson(std::get<0>(elem)->toAttrs());
|
||||||
obj["to"] = attrsToJson(elem.second->toAttrs());
|
obj["to"] = attrsToJson(std::get<1>(elem)->toAttrs());
|
||||||
|
obj["to"].update(attrsToJson(std::get<2>(elem)));
|
||||||
arr.emplace_back(std::move(obj));
|
arr.emplace_back(std::move(obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,16 +78,17 @@ void Registry::write(const Path & path)
|
||||||
|
|
||||||
void Registry::add(
|
void Registry::add(
|
||||||
const std::shared_ptr<const Input> & from,
|
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)
|
void Registry::remove(const std::shared_ptr<const Input> & input)
|
||||||
{
|
{
|
||||||
// FIXME: use C++20 std::erase.
|
// FIXME: use C++20 std::erase.
|
||||||
for (auto i = entries.begin(); i != entries.end(); )
|
for (auto i = entries.begin(); i != entries.end(); )
|
||||||
if (*i->first == *input)
|
if (*std::get<0>(*i) == *input)
|
||||||
i = entries.erase(i);
|
i = entries.erase(i);
|
||||||
else
|
else
|
||||||
++i;
|
++i;
|
||||||
|
@ -103,9 +114,10 @@ std::shared_ptr<Registry> getFlagRegistry()
|
||||||
|
|
||||||
void overrideRegistry(
|
void overrideRegistry(
|
||||||
const std::shared_ptr<const Input> & from,
|
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)
|
static std::shared_ptr<Registry> getGlobalRegistry(ref<Store> store)
|
||||||
|
@ -135,10 +147,11 @@ Registries getRegistries(ref<Store> store)
|
||||||
return registries;
|
return registries;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<const Input> lookupInRegistries(
|
std::pair<std::shared_ptr<const Input>, Input::Attrs> lookupInRegistries(
|
||||||
ref<Store> store,
|
ref<Store> store,
|
||||||
std::shared_ptr<const Input> input)
|
std::shared_ptr<const Input> input)
|
||||||
{
|
{
|
||||||
|
Input::Attrs extraAttrs;
|
||||||
int n = 0;
|
int n = 0;
|
||||||
|
|
||||||
restart:
|
restart:
|
||||||
|
@ -149,10 +162,12 @@ std::shared_ptr<const Input> 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.first->contains(*input)) {
|
auto from = std::get<0>(entry);
|
||||||
input = entry.second->applyOverrides(
|
if (from->contains(*input)) {
|
||||||
!entry.first->getRef() && input->getRef() ? input->getRef() : std::optional<std::string>(),
|
input = std::get<1>(entry)->applyOverrides(
|
||||||
!entry.first->getRev() && input->getRev() ? input->getRev() : std::optional<Hash>());
|
!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;
|
goto restart;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -161,7 +176,7 @@ std::shared_ptr<const Input> lookupInRegistries(
|
||||||
if (!input->isDirect())
|
if (!input->isDirect())
|
||||||
throw Error("cannot find flake '%s' in the flake registries", input->to_string());
|
throw Error("cannot find flake '%s' in the flake registries", input->to_string());
|
||||||
|
|
||||||
return input;
|
return {input, extraAttrs};
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "types.hh"
|
#include "types.hh"
|
||||||
|
#include "fetchers.hh"
|
||||||
|
|
||||||
namespace nix { class Store; }
|
namespace nix { class Store; }
|
||||||
|
|
||||||
namespace nix::fetchers {
|
namespace nix::fetchers {
|
||||||
|
|
||||||
struct Input;
|
|
||||||
|
|
||||||
struct Registry
|
struct Registry
|
||||||
{
|
{
|
||||||
enum RegistryType {
|
enum RegistryType {
|
||||||
|
@ -18,7 +17,13 @@ struct Registry
|
||||||
|
|
||||||
RegistryType type;
|
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)
|
Registry(RegistryType type)
|
||||||
: type(type)
|
: type(type)
|
||||||
|
@ -31,7 +36,8 @@ struct Registry
|
||||||
|
|
||||||
void add(
|
void add(
|
||||||
const std::shared_ptr<const Input> & from,
|
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);
|
void remove(const std::shared_ptr<const Input> & input);
|
||||||
};
|
};
|
||||||
|
@ -46,9 +52,10 @@ Registries getRegistries(ref<Store> store);
|
||||||
|
|
||||||
void overrideRegistry(
|
void overrideRegistry(
|
||||||
const std::shared_ptr<const Input> & from,
|
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,
|
ref<Store> store,
|
||||||
std::shared_ptr<const Input> input);
|
std::shared_ptr<const Input> input);
|
||||||
|
|
||||||
|
|
|
@ -70,8 +70,8 @@ struct CmdFlakeList : EvalCommand
|
||||||
registry->type == Registry::Flag ? "flags " :
|
registry->type == Registry::Flag ? "flags " :
|
||||||
registry->type == Registry::User ? "user " :
|
registry->type == Registry::User ? "user " :
|
||||||
"global",
|
"global",
|
||||||
entry.first->to_string(),
|
std::get<0>(entry)->to_string(),
|
||||||
entry.second->to_string());
|
std::get<1>(entry)->to_string());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -506,9 +506,11 @@ struct CmdFlakeAdd : MixEvalArgs, Command
|
||||||
{
|
{
|
||||||
auto fromRef = parseFlakeRef(fromUrl);
|
auto fromRef = parseFlakeRef(fromUrl);
|
||||||
auto toRef = parseFlakeRef(toUrl);
|
auto toRef = parseFlakeRef(toUrl);
|
||||||
|
fetchers::Input::Attrs extraAttrs;
|
||||||
|
if (toRef.subdir != "") extraAttrs["subdir"] = toRef.subdir;
|
||||||
auto userRegistry = fetchers::getUserRegistry();
|
auto userRegistry = fetchers::getUserRegistry();
|
||||||
userRegistry->remove(fromRef.input);
|
userRegistry->remove(fromRef.input);
|
||||||
userRegistry->add(fromRef.input, toRef.input);
|
userRegistry->add(fromRef.input, toRef.input, extraAttrs);
|
||||||
userRegistry->write(fetchers::getUserRegistryPath());
|
userRegistry->write(fetchers::getUserRegistryPath());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -555,7 +557,9 @@ struct CmdFlakePin : virtual Args, EvalCommand
|
||||||
auto userRegistry = fetchers::getUserRegistry();
|
auto userRegistry = fetchers::getUserRegistry();
|
||||||
userRegistry->remove(ref.input);
|
userRegistry->remove(ref.input);
|
||||||
auto [tree, resolved] = ref.resolve(store).input->fetchTree(store);
|
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