aboutsummaryrefslogtreecommitdiff
path: root/src/libexpr
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2020-02-01 23:33:44 +0100
committerEelco Dolstra <edolstra@gmail.com>2020-02-01 23:33:44 +0100
commitb9d64f931893120834fa54ebf084764d2e22ba33 (patch)
tree2a4e1abac0f7373a0e5c64d19c89c683d6aa9efd /src/libexpr
parent8451298b35353abafe385124cb55e8d4911032ad (diff)
Record TreeInfo in the lock file
Necessary for #3253.
Diffstat (limited to 'src/libexpr')
-rw-r--r--src/libexpr/flake/flake.cc26
-rw-r--r--src/libexpr/flake/lockfile.cc59
-rw-r--r--src/libexpr/flake/lockfile.hh9
3 files changed, 79 insertions, 15 deletions
diff --git a/src/libexpr/flake/flake.cc b/src/libexpr/flake/flake.cc
index 099cf4c58..59728e38d 100644
--- a/src/libexpr/flake/flake.cc
+++ b/src/libexpr/flake/flake.cc
@@ -478,7 +478,7 @@ LockedFlake lockFlake(
lockFlags.useRegistries, flakeCache);
newLocks.inputs.insert_or_assign(id,
- LockedInput(inputFlake.resolvedRef, inputFlake.originalRef, inputFlake.sourceInfo->info.narHash));
+ LockedInput(inputFlake.resolvedRef, inputFlake.originalRef, inputFlake.sourceInfo->info));
/* Recursively process the inputs of this
flake. Also, unless we already have this
@@ -497,7 +497,7 @@ LockedFlake lockFlake(
auto [sourceInfo, resolvedRef] = getNonFlake(state, input.ref,
lockFlags.useRegistries, flakeCache);
newLocks.inputs.insert_or_assign(id,
- LockedInput(resolvedRef, input.ref, sourceInfo.info.narHash));
+ LockedInput(resolvedRef, input.ref, sourceInfo.info));
}
}
}
@@ -604,9 +604,14 @@ static void prim_callFlake(EvalState & state, const Pos & pos, Value * * args, V
if (lazyInput->isFlake) {
auto flake = getFlake(state, lazyInput->lockedInput.ref, false);
- if (flake.sourceInfo->info.narHash != lazyInput->lockedInput.narHash)
- throw Error("the content hash of flake '%s' doesn't match the hash recorded in the referring lockfile",
- lazyInput->lockedInput.ref);
+ if (flake.sourceInfo->info.narHash != lazyInput->lockedInput.info.narHash)
+ throw Error("the content hash of flake '%s' (%s) doesn't match the hash recorded in the referring lock file (%s)",
+ lazyInput->lockedInput.ref,
+ flake.sourceInfo->info.narHash.to_string(SRI),
+ lazyInput->lockedInput.info.narHash.to_string(SRI));
+
+ // FIXME: check all the other attributes in lockedInput.info
+ // once we've dropped support for lock file version 4.
assert(flake.sourceInfo->storePath == lazyInput->lockedInput.computeStorePath(*state.store));
@@ -615,9 +620,14 @@ static void prim_callFlake(EvalState & state, const Pos & pos, Value * * args, V
FlakeCache flakeCache;
auto [sourceInfo, resolvedRef] = getNonFlake(state, lazyInput->lockedInput.ref, false, flakeCache);
- if (sourceInfo.info.narHash != lazyInput->lockedInput.narHash)
- throw Error("the content hash of repository '%s' doesn't match the hash recorded in the referring lockfile",
- lazyInput->lockedInput.ref);
+ if (sourceInfo.info.narHash != lazyInput->lockedInput.info.narHash)
+ throw Error("the content hash of repository '%s' (%s) doesn't match the hash recorded in the referring lock file (%s)",
+ lazyInput->lockedInput.ref,
+ sourceInfo.info.narHash.to_string(SRI),
+ lazyInput->lockedInput.info.narHash.to_string(SRI));
+
+ // FIXME: check all the other attributes in lockedInput.info
+ // once we've dropped support for lock file version 4.
assert(sourceInfo.storePath == lazyInput->lockedInput.computeStorePath(*state.store));
diff --git a/src/libexpr/flake/lockfile.cc b/src/libexpr/flake/lockfile.cc
index 60fb914f9..6773b2844 100644
--- a/src/libexpr/flake/lockfile.cc
+++ b/src/libexpr/flake/lockfile.cc
@@ -44,28 +44,81 @@ FlakeRef getFlakeRef(
throw Error("attribute '%s' missing in lock file", version4Attr);
}
+static TreeInfo parseTreeInfo(const nlohmann::json & json)
+{
+ TreeInfo info;
+
+ auto i = json.find("info");
+ if (i != json.end()) {
+ const nlohmann::json & i2(*i);
+
+ auto j = i2.find("narHash");
+ if (j != i2.end())
+ info.narHash = Hash((std::string) *j);
+ else
+ throw Error("attribute 'narHash' missing in lock file");
+
+ j = i2.find("rev");
+ if (j != i2.end())
+ info.rev = Hash((std::string) *j, htSHA1);
+
+ j = i2.find("revCount");
+ if (j != i2.end())
+ info.revCount = *j;
+
+ j = i2.find("lastModified");
+ if (j != i2.end())
+ info.lastModified = *j;
+
+ return info;
+ }
+
+ i = json.find("narHash");
+ if (i != json.end()) {
+ info.narHash = Hash((std::string) *i);
+ return info;
+ }
+
+ throw Error("attribute 'info' missing in lock file");
+}
+
LockedInput::LockedInput(const nlohmann::json & json)
: LockedInputs(json)
, ref(getFlakeRef(json, "url", "uri", "resolvedRef"))
, originalRef(getFlakeRef(json, "originalUrl", "originalUri", "originalRef"))
- , narHash(Hash((std::string) json["narHash"]))
+ , info(parseTreeInfo(json))
{
if (!ref.isImmutable())
throw Error("lockfile contains mutable flakeref '%s'", ref);
}
+static nlohmann::json treeInfoToJson(const TreeInfo & info)
+{
+ nlohmann::json json;
+ assert(info.narHash);
+ json["narHash"] = info.narHash.to_string(SRI);
+ if (info.rev)
+ json["rev"] = info.rev->gitRev();
+ if (info.revCount)
+ json["revCount"] = *info.revCount;
+ if (info.lastModified)
+ json["lastModified"] = *info.lastModified;
+ return json;
+}
+
nlohmann::json LockedInput::toJson() const
{
auto json = LockedInputs::toJson();
json["originalRef"] = fetchers::attrsToJson(originalRef.toAttrs());
json["resolvedRef"] = fetchers::attrsToJson(ref.toAttrs());
- json["narHash"] = narHash.to_string(SRI); // FIXME
+ json["info"] = treeInfoToJson(info);
return json;
}
StorePath LockedInput::computeStorePath(Store & store) const
{
- return store.makeFixedOutputPath(true, narHash, "source");
+ assert(info.narHash);
+ return store.makeFixedOutputPath(true, info.narHash, "source");
}
LockedInputs::LockedInputs(const nlohmann::json & json)
diff --git a/src/libexpr/flake/lockfile.hh b/src/libexpr/flake/lockfile.hh
index a9710524b..d1cbf7c06 100644
--- a/src/libexpr/flake/lockfile.hh
+++ b/src/libexpr/flake/lockfile.hh
@@ -36,10 +36,10 @@ struct LockedInputs
struct LockedInput : LockedInputs
{
FlakeRef ref, originalRef;
- Hash narHash;
+ TreeInfo info;
- LockedInput(const FlakeRef & ref, const FlakeRef & originalRef, const Hash & narHash)
- : ref(ref), originalRef(originalRef), narHash(narHash)
+ LockedInput(const FlakeRef & ref, const FlakeRef & originalRef, const TreeInfo & info)
+ : ref(ref), originalRef(originalRef), info(info)
{ }
LockedInput(const nlohmann::json & json);
@@ -48,7 +48,8 @@ struct LockedInput : LockedInputs
{
return
ref == other.ref
- && narHash == other.narHash
+ && originalRef == other.originalRef
+ && info == other.info
&& inputs == other.inputs;
}