diff options
author | Eelco Dolstra <edolstra@gmail.com> | 2020-01-31 19:16:40 +0100 |
---|---|---|
committer | Eelco Dolstra <edolstra@gmail.com> | 2020-01-31 19:16:40 +0100 |
commit | 8414685c0f0c0d744c70d438894e4ecd7a078808 (patch) | |
tree | 3c7ca4bf6116f0d7dc863f4737518213767e7455 /src/libexpr/flake | |
parent | dbefe9e6b8e4db54be0bd63d3318019d0e3043ac (diff) |
Change lock file format to use an attribute representation of flake refs rather than URLs
Diffstat (limited to 'src/libexpr/flake')
-rw-r--r-- | src/libexpr/flake/flakeref.cc | 20 | ||||
-rw-r--r-- | src/libexpr/flake/flakeref.hh | 7 | ||||
-rw-r--r-- | src/libexpr/flake/lockfile.cc | 54 |
3 files changed, 69 insertions, 12 deletions
diff --git a/src/libexpr/flake/flakeref.cc b/src/libexpr/flake/flakeref.cc index 7b840bce5..194332674 100644 --- a/src/libexpr/flake/flakeref.cc +++ b/src/libexpr/flake/flakeref.cc @@ -14,12 +14,19 @@ const static std::string subDirElemRegex = "(?:[a-zA-Z0-9_-]+[a-zA-Z0-9._-]*)"; const static std::string subDirRegex = subDirElemRegex + "(?:/" + subDirElemRegex + ")*"; #endif - std::string FlakeRef::to_string() const { return input->to_string(); } +fetchers::Input::Attrs FlakeRef::toAttrs() const +{ + auto attrs = input->toAttrs(); + if (subdir != "") + attrs.emplace("subdir", subdir); + return attrs; +} + bool FlakeRef::isDirect() const { return input->isDirect(); @@ -36,7 +43,7 @@ std::ostream & operator << (std::ostream & str, const FlakeRef & flakeRef) return str; } -bool FlakeRef::operator==(const FlakeRef & other) const +bool FlakeRef::operator ==(const FlakeRef & other) const { return *input == *other.input && subdir == other.subdir; } @@ -166,4 +173,13 @@ std::optional<std::pair<FlakeRef, std::string>> maybeParseFlakeRefWithFragment( } } +FlakeRef FlakeRef::fromAttrs(const fetchers::Input::Attrs & attrs) +{ + auto attrs2(attrs); + attrs2.erase("subdir"); + return FlakeRef( + fetchers::inputFromAttrs(attrs2), + fetchers::maybeGetStrAttr(attrs, "subdir").value_or("")); +} + } diff --git a/src/libexpr/flake/flakeref.hh b/src/libexpr/flake/flakeref.hh index f552c99d8..9febc639d 100644 --- a/src/libexpr/flake/flakeref.hh +++ b/src/libexpr/flake/flakeref.hh @@ -2,6 +2,7 @@ #include "types.hh" #include "hash.hh" +#include "fetchers/fetchers.hh" #include <variant> @@ -9,8 +10,6 @@ namespace nix { class Store; -namespace fetchers { struct Input; } - typedef std::string FlakeId; struct FlakeRef @@ -30,6 +29,8 @@ struct FlakeRef // FIXME: change to operator <<. std::string to_string() const; + fetchers::Input::Attrs toAttrs() const; + /* Check whether this is a "direct" flake reference, that is, not a flake ID, which requires a lookup in the flake registry. */ bool isDirect() const; @@ -39,6 +40,8 @@ struct FlakeRef bool isImmutable() const; FlakeRef resolve(ref<Store> store) const; + + static FlakeRef fromAttrs(const fetchers::Input::Attrs & attrs); }; std::ostream & operator << (std::ostream & str, const FlakeRef & flakeRef); diff --git a/src/libexpr/flake/lockfile.cc b/src/libexpr/flake/lockfile.cc index 2696d4710..60fb914f9 100644 --- a/src/libexpr/flake/lockfile.cc +++ b/src/libexpr/flake/lockfile.cc @@ -6,10 +6,48 @@ namespace nix::flake { +FlakeRef flakeRefFromJson(const nlohmann::json & json) +{ + fetchers::Input::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 + throw Error("unsupported input attribute type in lock file"); + } + + return FlakeRef::fromAttrs(attrs); +} + +FlakeRef getFlakeRef( + const nlohmann::json & json, + const char * version3Attr1, + const char * version3Attr2, + const char * version4Attr) +{ + auto i = json.find(version4Attr); + if (i != json.end()) + return flakeRefFromJson(*i); + + // FIXME: remove these. + i = json.find(version3Attr1); + if (i != json.end()) + return parseFlakeRef(*i); + + i = json.find(version3Attr2); + if (i != json.end()) + return parseFlakeRef(*i); + + throw Error("attribute '%s' missing in lock file", version4Attr); +} + LockedInput::LockedInput(const nlohmann::json & json) : LockedInputs(json) - , ref(parseFlakeRef(json.value("url", json.value("uri", "")))) - , originalRef(parseFlakeRef(json.value("originalUrl", json.value("originalUri", "")))) + , ref(getFlakeRef(json, "url", "uri", "resolvedRef")) + , originalRef(getFlakeRef(json, "originalUrl", "originalUri", "originalRef")) , narHash(Hash((std::string) json["narHash"])) { if (!ref.isImmutable()) @@ -19,9 +57,9 @@ LockedInput::LockedInput(const nlohmann::json & json) nlohmann::json LockedInput::toJson() const { auto json = LockedInputs::toJson(); - json["url"] = ref.to_string(); - json["originalUrl"] = originalRef.to_string(); - json["narHash"] = narHash.to_string(SRI); + json["originalRef"] = fetchers::attrsToJson(originalRef.toAttrs()); + json["resolvedRef"] = fetchers::attrsToJson(ref.toAttrs()); + json["narHash"] = narHash.to_string(SRI); // FIXME return json; } @@ -91,7 +129,7 @@ void LockedInputs::removeInput(const InputPath & path) nlohmann::json LockFile::toJson() const { auto json = LockedInputs::toJson(); - json["version"] = 3; + json["version"] = 4; return json; } @@ -101,7 +139,7 @@ LockFile LockFile::read(const Path & path) auto json = nlohmann::json::parse(readFile(path)); auto version = json.value("version", 0); - if (version != 3) + if (version != 3 && version != 4) throw Error("lock file '%s' has unsupported version %d", path, version); return LockFile(json); @@ -111,7 +149,7 @@ LockFile LockFile::read(const Path & path) std::ostream & operator <<(std::ostream & stream, const LockFile & lockFile) { - stream << lockFile.toJson().dump(4); // '4' = indentation in json file + stream << lockFile.toJson().dump(2); return stream; } |