diff options
author | Eelco Dolstra <edolstra@gmail.com> | 2019-07-12 13:29:54 +0200 |
---|---|---|
committer | Eelco Dolstra <edolstra@gmail.com> | 2019-07-12 13:29:54 +0200 |
commit | b29cec76971ff1949415f76c82fa0ecf699ac264 (patch) | |
tree | 647165a0a2dc2cefb8d398776337de8d3f8aaa86 | |
parent | bd62290c23fa15181e8af75c5055e104900f8532 (diff) |
Don't write lock files if they have dirty inputs
-rw-r--r-- | src/libexpr/flake/flake.cc | 27 | ||||
-rw-r--r-- | src/libexpr/flake/flakeref.hh | 6 | ||||
-rw-r--r-- | src/libexpr/flake/lockfile.cc | 11 | ||||
-rw-r--r-- | src/libexpr/flake/lockfile.hh | 4 |
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. */ |