aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2019-07-12 13:29:54 +0200
committerEelco Dolstra <edolstra@gmail.com>2019-07-12 13:29:54 +0200
commitb29cec76971ff1949415f76c82fa0ecf699ac264 (patch)
tree647165a0a2dc2cefb8d398776337de8d3f8aaa86
parentbd62290c23fa15181e8af75c5055e104900f8532 (diff)
Don't write lock files if they have dirty inputs
-rw-r--r--src/libexpr/flake/flake.cc27
-rw-r--r--src/libexpr/flake/flakeref.hh6
-rw-r--r--src/libexpr/flake/lockfile.cc11
-rw-r--r--src/libexpr/flake/lockfile.hh4
4 files changed, 37 insertions, 11 deletions
diff --git a/src/libexpr/flake/flake.cc b/src/libexpr/flake/flake.cc
index abbb9a3e1..e6cef502c 100644
--- a/src/libexpr/flake/flake.cc
+++ b/src/libexpr/flake/flake.cc
@@ -405,17 +405,22 @@ ResolvedFlake resolveFlake(EvalState & state, const FlakeRef & topRef, HandleLoc
if (!(lockFile == oldLockFile)) {
if (allowedToWrite(handleLockFile)) {
if (auto refData = std::get_if<FlakeRef::IsPath>(&topRef.data)) {
- lockFile.write(refData->path + (topRef.subdir == "" ? "" : "/" + topRef.subdir) + "/flake.lock");
-
- // Hack: Make sure that flake.lock is visible to Git, so it ends up in the Nix store.
- runProgram("git", true, { "-C", refData->path, "add",
- "--force",
- "--intent-to-add",
- (topRef.subdir == "" ? "" : topRef.subdir + "/") + "flake.lock" });
+ if (lockFile.isDirty())
+ warn("will not write lock file of flake '%s' because it has a dirty input", topRef);
+ else {
+ lockFile.write(refData->path + (topRef.subdir == "" ? "" : "/" + topRef.subdir) + "/flake.lock");
+
+ // Hack: Make sure that flake.lock is visible to Git, so it ends up in the Nix store.
+ runProgram("git", true,
+ { "-C", refData->path, "add",
+ "--force",
+ "--intent-to-add",
+ (topRef.subdir == "" ? "" : topRef.subdir + "/") + "flake.lock" });
+ }
} else
- warn("cannot write lockfile of remote flake '%s'", topRef);
+ warn("cannot write lock file of remote flake '%s'", topRef);
} else if (handleLockFile != AllPure && handleLockFile != TopRefUsesRegistries)
- warn("using updated lockfile without writing it to file");
+ warn("using updated lock file without writing it to file");
}
return ResolvedFlake(std::move(flake), std::move(lockFile));
@@ -624,8 +629,8 @@ const Registries EvalState::getFlakeRegistries()
Fingerprint ResolvedFlake::getFingerprint() const
{
- // FIXME: as an optimization, if the flake contains a lockfile and
- // we haven't changed it, then it's sufficient to use
+ // FIXME: as an optimization, if the flake contains a lock file
+ // and we haven't changed it, then it's sufficient to use
// flake.sourceInfo.storePath for the fingerprint.
return hashString(htSHA256,
fmt("%s;%s", flake.sourceInfo.storePath, lockFile));
diff --git a/src/libexpr/flake/flakeref.hh b/src/libexpr/flake/flakeref.hh
index 52bb82ddb..082dd8c26 100644
--- a/src/libexpr/flake/flakeref.hh
+++ b/src/libexpr/flake/flakeref.hh
@@ -176,6 +176,12 @@ struct FlakeRef
bool isImmutable() const;
FlakeRef baseRef() const;
+
+ bool isDirty() const
+ {
+ return std::get_if<FlakeRef::IsPath>(&data)
+ && rev == Hash(rev->type);
+ }
};
std::ostream & operator << (std::ostream & str, const FlakeRef & flakeRef);
diff --git a/src/libexpr/flake/lockfile.cc b/src/libexpr/flake/lockfile.cc
index 97c748c66..15f2e2e8e 100644
--- a/src/libexpr/flake/lockfile.cc
+++ b/src/libexpr/flake/lockfile.cc
@@ -66,6 +66,17 @@ nlohmann::json FlakeInputs::toJson() const
return json;
}
+bool FlakeInputs::isDirty() const
+{
+ for (auto & i : flakeInputs)
+ if (i.second.ref.isDirty() || i.second.isDirty()) return true;
+
+ for (auto & i : nonFlakeInputs)
+ if (i.second.ref.isDirty()) return true;
+
+ return false;
+}
+
nlohmann::json LockFile::toJson() const
{
auto json = FlakeInputs::toJson();
diff --git a/src/libexpr/flake/lockfile.hh b/src/libexpr/flake/lockfile.hh
index b76124190..7077db3cd 100644
--- a/src/libexpr/flake/lockfile.hh
+++ b/src/libexpr/flake/lockfile.hh
@@ -53,6 +53,10 @@ struct FlakeInputs
FlakeInputs(const nlohmann::json & json);
nlohmann::json toJson() const;
+
+ /* A lock file is dirty if it contains a dirty flakeref
+ (i.e. reference to a dirty working tree). */
+ bool isDirty() const;
};
/* Lock file information about a flake input. */