diff options
Diffstat (limited to 'src/libstore')
-rw-r--r-- | src/libstore/build.cc | 54 | ||||
-rw-r--r-- | src/libstore/globals.cc | 1 | ||||
-rw-r--r-- | src/libstore/globals.hh | 8 | ||||
-rw-r--r-- | src/libstore/remote-store.cc | 2 |
4 files changed, 52 insertions, 13 deletions
diff --git a/src/libstore/build.cc b/src/libstore/build.cc index f680b3737895..3830d7a671e8 100644 --- a/src/libstore/build.cc +++ b/src/libstore/build.cc @@ -747,6 +747,11 @@ private: /* Number of bytes received from the builder's stdout/stderr. */ unsigned long logSize; + /* The most recent log lines. */ + std::list<std::string> logTail; + + std::string currentLogLine; + /* Pipe for the builder's standard output/error. */ Pipe builderOut; @@ -872,6 +877,7 @@ private: /* Callback used by the worker to write to the log. */ void handleChildOutput(int fd, const string & data) override; void handleEOF(int fd) override; + void flushLine(); /* Return the set of (in)valid paths. */ PathSet checkPathValidity(bool returnValid, bool checkHash); @@ -1462,11 +1468,19 @@ void DerivationGoal::buildDone() if (pathExists(chrootRootDir + i)) rename((chrootRootDir + i).c_str(), i.c_str()); + std::string msg = (format("builder for ‘%1%’ %2%") + % drvPath % statusToString(status)).str(); + + if (!settings.verboseBuild && !logTail.empty()) { + msg += (format("; last %d log lines:") % logTail.size()).str(); + for (auto & line : logTail) + msg += "\n " + line; + } + if (diskFull) - printMsg(lvlError, "note: build failure may have been caused by lack of free disk space"); + msg += "\nnote: build failure may have been caused by lack of free disk space"; - throw BuildError(format("builder for ‘%1%’ %2%") - % drvPath % statusToString(status)); + throw BuildError(msg); } /* Compute the FS closure of the outputs and register them as @@ -2920,8 +2934,20 @@ void DerivationGoal::handleChildOutput(int fd, const string & data) done(BuildResult::LogLimitExceeded); return; } - if (verbosity >= settings.buildVerbosity) - printMsg(lvlError, filterANSIEscapes(data, true)); // FIXME + + for (size_t pos = 0; true; ) { + auto newline = data.find('\n', pos); + + if (newline == std::string::npos) { + currentLogLine.append(data, pos, std::string::npos); + break; + } + + currentLogLine.append(data, pos, newline - pos); + flushLine(); + pos = newline + 1; + } + if (bzLogFile) { int err; BZ2_bzWrite(&err, bzLogFile, (unsigned char *) data.data(), data.size()); @@ -2937,10 +2963,23 @@ void DerivationGoal::handleChildOutput(int fd, const string & data) void DerivationGoal::handleEOF(int fd) { + flushLine(); worker.wakeUp(shared_from_this()); } +void DerivationGoal::flushLine() +{ + if (settings.verboseBuild) + printMsg(lvlInfo, filterANSIEscapes(currentLogLine, true)); + else { + logTail.push_back(currentLogLine); + if (logTail.size() > settings.logLines) logTail.pop_front(); + } + currentLogLine = ""; +} + + PathSet DerivationGoal::checkPathValidity(bool returnValid, bool checkHash) { PathSet result; @@ -3341,10 +3380,7 @@ void SubstitutionGoal::finished() void SubstitutionGoal::handleChildOutput(int fd, const string & data) { assert(fd == logPipe.readSide); - if (verbosity >= settings.buildVerbosity) - printMsg(lvlError, data); // FIXME - /* Don't write substitution output to a log file for now. We - probably should, though. */ + printMsg(lvlError, data); // FIXME } diff --git a/src/libstore/globals.cc b/src/libstore/globals.cc index f4c41d715f35..90539ea85420 100644 --- a/src/libstore/globals.cc +++ b/src/libstore/globals.cc @@ -28,7 +28,6 @@ Settings::Settings() keepFailed = false; keepGoing = false; tryFallback = false; - buildVerbosity = lvlError; maxBuildJobs = 1; buildCores = 1; #ifdef _SC_NPROCESSORS_ONLN diff --git a/src/libstore/globals.hh b/src/libstore/globals.hh index 8fa49e2dc120..60251ef421bf 100644 --- a/src/libstore/globals.hh +++ b/src/libstore/globals.hh @@ -78,8 +78,12 @@ struct Settings { instead. */ bool tryFallback; - /* Verbosity level for build output. */ - Verbosity buildVerbosity; + /* Whether to show build log output in real time. */ + bool verboseBuild = true; + + /* If verboseBuild is false, the number of lines of the tail of + the log to show if a build fails. */ + size_t logLines = 10; /* Maximum number of parallel build jobs. 0 means unlimited. */ unsigned int maxBuildJobs; diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc index 831f4a83e029..4663291b9171 100644 --- a/src/libstore/remote-store.cc +++ b/src/libstore/remote-store.cc @@ -120,7 +120,7 @@ void RemoteStore::setOptions(ref<Connection> conn) if (GET_PROTOCOL_MINOR(conn->daemonVersion) >= 2) conn->to << settings.useBuildHook; if (GET_PROTOCOL_MINOR(conn->daemonVersion) >= 4) - conn->to << settings.buildVerbosity + conn->to << (settings.verboseBuild ? lvlError : lvlVomit) << 0 // obsolete log type << 0 /* obsolete print build trace */; if (GET_PROTOCOL_MINOR(conn->daemonVersion) >= 6) |