guix-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

09/09: daemon: rounds: Keep the differing output if -K is given.


From: Ludovic Courtès
Subject: 09/09: daemon: rounds: Keep the differing output if -K is given.
Date: Tue, 31 May 2016 12:34:02 +0000 (UTC)

civodul pushed a commit to branch master
in repository guix.

commit b4528110c647b6fe9389730826941bea05801394
Author: Eelco Dolstra <address@hidden>
Date:   Tue Jan 12 18:25:57 2016 +0100

    daemon: rounds: Keep the differing output if -K is given.
    
    Regardless of -K, we now also print which output differs.
---
 doc/guix.texi         |    4 ++++
 nix/libstore/build.cc |   45 ++++++++++++++++++++++++++++++++++++++-------
 2 files changed, 42 insertions(+), 7 deletions(-)

diff --git a/doc/guix.texi b/doc/guix.texi
index cd4e550..4222e01 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -998,6 +998,10 @@ consecutive build results are not bit-for-bit identical.  
Note that this
 setting can be overridden by clients such as @command{guix build}
 (@pxref{Invoking guix build}).
 
+When used in conjunction with @option{--keep-failed}, the differing
+output is kept in the store, under @file{/gnu/store/@dots{}-check}.
+This makes it easy to look for differences between the two results.
+
 @item --debug
 Produce debugging output.
 
diff --git a/nix/libstore/build.cc b/nix/libstore/build.cc
index d51705b..2d3960b 100644
--- a/nix/libstore/build.cc
+++ b/nix/libstore/build.cc
@@ -2320,6 +2320,8 @@ void DerivationGoal::registerOutputs()
        outputs to allow hard links between outputs. */
     InodesSeen inodesSeen;
 
+    Path checkSuffix = "-check";
+
     /* Check whether the output paths were created, and grep each
        output path to determine what other paths it references.  Also make all
        output paths read-only. */
@@ -2433,7 +2435,7 @@ void DerivationGoal::registerOutputs()
             ValidPathInfo info = worker.store.queryPathInfo(path);
             if (hash.first != info.hash) {
                 if (settings.keepFailed) {
-                    Path dst = path + "-check";
+                    Path dst = path + checkSuffix;
                     if (pathExists(dst)) deletePath(dst);
                     if (rename(actualPath.c_str(), dst.c_str()))
                         throw SysError(format("renaming `%1%' to `%2%'") % 
actualPath % dst);
@@ -2487,9 +2489,11 @@ void DerivationGoal::registerOutputs()
         checkRefs("disallowedReferences", false, false);
         checkRefs("disallowedRequisites", false, true);
 
-        worker.store.optimisePath(path); // FIXME: combine with 
scanForReferences()
+        if (curRound == nrRounds) {
+            worker.store.optimisePath(path); // FIXME: combine with 
scanForReferences()
 
-        worker.store.markContentsGood(path);
+            worker.store.markContentsGood(path);
+        }
 
         ValidPathInfo info;
         info.path = path;
@@ -2502,10 +2506,37 @@ void DerivationGoal::registerOutputs()
 
     if (buildMode == bmCheck) return;
 
-    if (curRound > 1 && prevInfos != infos)
-        throw NotDeterministic(
-            format("result of ‘%1%’ differs from previous round; rejecting as 
non-deterministic")
-            % drvPath);
+    /* Compare the result with the previous round, and report which
+       path is different, if any.*/
+    if (curRound > 1 && prevInfos != infos) {
+        assert(prevInfos.size() == infos.size());
+        for (auto i = prevInfos.begin(), j = infos.begin(); i != 
prevInfos.end(); ++i, ++j)
+            if (!(*i == *j)) {
+                Path prev = i->path + checkSuffix;
+                if (pathExists(prev))
+                    throw NotDeterministic(
+                        format("output ‘%1%’ of ‘%2%’ differs from ‘%3%’ from 
previous round")
+                        % i->path % drvPath % prev);
+                else
+                    throw NotDeterministic(
+                        format("output ‘%1%’ of ‘%2%’ differs from previous 
round")
+                        % i->path % drvPath);
+            }
+        assert(false); // shouldn't happen
+    }
+
+    if (settings.keepFailed) {
+        for (auto & i : drv.outputs) {
+            Path prev = i.second.path + checkSuffix;
+            if (pathExists(prev)) deletePath(prev);
+            if (curRound < nrRounds) {
+                Path dst = i.second.path + checkSuffix;
+                if (rename(i.second.path.c_str(), dst.c_str()))
+                    throw SysError(format("renaming ‘%1%’ to ‘%2%’") % 
i.second.path % dst);
+            }
+        }
+
+    }
 
     if (curRound < nrRounds) {
         prevInfos = infos;



reply via email to

[Prev in Thread] Current Thread [Next in Thread]