Permalink
Browse files

Add a hook to run diffoscope when non-determinism is detected

  • Loading branch information...
edolstra committed Dec 7, 2016
1 parent b070606 commit 9a313469a4bdea2d1e8df24d16289dc2a172a169
Showing with 33 additions and 7 deletions.
  1. +32 −7 src/libstore/build.cc
  2. +1 −0 src/nix-store/nix-store.cc
@@ -2688,6 +2688,8 @@ void DerivationGoal::registerOutputs()
InodesSeen inodesSeen;
Path checkSuffix = "-check";
bool runDiffHook = settings.get("run-diff-hook", false);
bool keepPreviousRound = settings.keepFailed || runDiffHook;
/* Check whether the output paths were created, and grep each
output path to determine what other paths it references. Also make all
@@ -2919,25 +2921,39 @@ void DerivationGoal::registerOutputs()
if (!(*i == *j)) {
result.isNonDeterministic = true;
Path prev = i->path + checkSuffix;
auto msg = pathExists(prev)
bool prevExists = keepPreviousRound && pathExists(prev);
auto msg = prevExists
? fmt("output ‘%1%’ of ‘%2%’ differs from ‘%3%’ from previous round", i->path, drvPath, prev)
: fmt("output ‘%1%’ of ‘%2%’ differs from previous round", i->path, drvPath);
auto diffHook = settings.get("diff-hook", std::string(""));
if (prevExists && diffHook != "" && runDiffHook) {
try {
auto diff = runProgram(diffHook, true, {prev, i->path});
if (diff != "")
printError(chomp(diff));
} catch (Error & error) {
printError("diff hook execution failed: %s", error.what());
}
}
if (settings.get("enforce-determinism", true))
throw NotDeterministic(msg);
printError(msg);
curRound = nrRounds; // we know enough, bail out early
}
}
if (settings.keepFailed) {
/* If this is the first round of several, then move the output out
of the way. */
if (nrRounds > 1 && curRound == 1 && curRound < nrRounds && keepPreviousRound) {
for (auto & i : drv->outputs) {
Path prev = i.second.path + checkSuffix;
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);
}
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);
}
}
@@ -2946,6 +2962,15 @@ void DerivationGoal::registerOutputs()
return;
}
/* Remove the -check directories if we're done. FIXME: keep them
if the result was not determistic? */
if (curRound == nrRounds) {
for (auto & i : drv->outputs) {
Path prev = i.second.path + checkSuffix;
deletePath(prev);
}
}
/* Register each output path as valid, and register the sets of
paths referenced by each of them. If there are cycles in the
outputs, this will fail. */
@@ -843,6 +843,7 @@ static void opServe(Strings opFlags, Strings opArgs)
if (GET_PROTOCOL_MINOR(clientVersion) >= 3) {
settings.set("build-repeat", std::to_string(readInt(in)));
settings.set("enforce-determinism", readInt(in) != 0 ? "true" : "false");
settings.set("run-diff-hook", "true");
}
settings.printRepeatedBuilds = false;
};

0 comments on commit 9a31346

Please sign in to comment.