forked from lix-project/lix
950b46821f
The attributes previously stored in TreeInfo (narHash, revCount, lastModified) are now stored in Input. This makes it less arbitrary what attributes are stored where. As a result, the lock file format has changed. An entry like "info": { "lastModified": 1585405475, "narHash": "sha256-bESW0n4KgPmZ0luxvwJ+UyATrC6iIltVCsGdLiphVeE=" }, "locked": { "owner": "NixOS", "repo": "nixpkgs", "rev": "b88ff468e9850410070d4e0ccd68c7011f15b2be", "type": "github" }, is now stored as "locked": { "owner": "NixOS", "repo": "nixpkgs", "rev": "b88ff468e9850410070d4e0ccd68c7011f15b2be", "type": "github", "lastModified": 1585405475, "narHash": "sha256-bESW0n4KgPmZ0luxvwJ+UyATrC6iIltVCsGdLiphVeE=" }, The 'Input' class is now a dumb set of attributes. All the fetcher implementations subclass InputScheme, not Input. This simplifies the API. Also, fix substitution of flake inputs. This was broken since lazy flake fetching started using fetchTree internally.
108 lines
3.1 KiB
C++
108 lines
3.1 KiB
C++
#include "attrs.hh"
|
|
#include "fetchers.hh"
|
|
|
|
#include <nlohmann/json.hpp>
|
|
|
|
namespace nix::fetchers {
|
|
|
|
Attrs jsonToAttrs(const nlohmann::json & json)
|
|
{
|
|
Attrs attrs;
|
|
|
|
for (auto & i : json.items()) {
|
|
if (i.value().is_number())
|
|
attrs.emplace(i.key(), i.value().get<int64_t>());
|
|
else if (i.value().is_string())
|
|
attrs.emplace(i.key(), i.value().get<std::string>());
|
|
else if (i.value().is_boolean())
|
|
attrs.emplace(i.key(), i.value().get<bool>());
|
|
else
|
|
throw Error("unsupported input attribute type in lock file");
|
|
}
|
|
|
|
return attrs;
|
|
}
|
|
|
|
nlohmann::json attrsToJson(const Attrs & attrs)
|
|
{
|
|
nlohmann::json json;
|
|
for (auto & attr : attrs) {
|
|
if (auto v = std::get_if<uint64_t>(&attr.second)) {
|
|
json[attr.first] = *v;
|
|
} else if (auto v = std::get_if<std::string>(&attr.second)) {
|
|
json[attr.first] = *v;
|
|
} else if (auto v = std::get_if<Explicit<bool>>(&attr.second)) {
|
|
json[attr.first] = v->t;
|
|
} else abort();
|
|
}
|
|
return json;
|
|
}
|
|
|
|
std::optional<std::string> maybeGetStrAttr(const Attrs & attrs, const std::string & name)
|
|
{
|
|
auto i = attrs.find(name);
|
|
if (i == attrs.end()) return {};
|
|
if (auto v = std::get_if<std::string>(&i->second))
|
|
return *v;
|
|
throw Error("input attribute '%s' is not a string %s", name, attrsToJson(attrs).dump());
|
|
}
|
|
|
|
std::string getStrAttr(const Attrs & attrs, const std::string & name)
|
|
{
|
|
auto s = maybeGetStrAttr(attrs, name);
|
|
if (!s)
|
|
throw Error("input attribute '%s' is missing", name);
|
|
return *s;
|
|
}
|
|
|
|
std::optional<uint64_t> maybeGetIntAttr(const Attrs & attrs, const std::string & name)
|
|
{
|
|
auto i = attrs.find(name);
|
|
if (i == attrs.end()) return {};
|
|
if (auto v = std::get_if<uint64_t>(&i->second))
|
|
return *v;
|
|
throw Error("input attribute '%s' is not an integer", name);
|
|
}
|
|
|
|
uint64_t getIntAttr(const Attrs & attrs, const std::string & name)
|
|
{
|
|
auto s = maybeGetIntAttr(attrs, name);
|
|
if (!s)
|
|
throw Error("input attribute '%s' is missing", name);
|
|
return *s;
|
|
}
|
|
|
|
std::optional<bool> maybeGetBoolAttr(const Attrs & attrs, const std::string & name)
|
|
{
|
|
auto i = attrs.find(name);
|
|
if (i == attrs.end()) return {};
|
|
if (auto v = std::get_if<Explicit<bool>>(&i->second))
|
|
return v->t;
|
|
throw Error("input attribute '%s' is not a Boolean", name);
|
|
}
|
|
|
|
bool getBoolAttr(const Attrs & attrs, const std::string & name)
|
|
{
|
|
auto s = maybeGetBoolAttr(attrs, name);
|
|
if (!s)
|
|
throw Error("input attribute '%s' is missing", name);
|
|
return *s;
|
|
}
|
|
|
|
std::map<std::string, std::string> attrsToQuery(const Attrs & attrs)
|
|
{
|
|
std::map<std::string, std::string> query;
|
|
for (auto & attr : attrs) {
|
|
if (auto v = std::get_if<uint64_t>(&attr.second)) {
|
|
query.insert_or_assign(attr.first, fmt("%d", *v));
|
|
} else if (auto v = std::get_if<std::string>(&attr.second)) {
|
|
query.insert_or_assign(attr.first, *v);
|
|
} else if (auto v = std::get_if<Explicit<bool>>(&attr.second)) {
|
|
query.insert_or_assign(attr.first, v->t ? "1" : "0");
|
|
} else abort();
|
|
}
|
|
return query;
|
|
}
|
|
|
|
}
|