repl: respect --print-build-logs & fix memory leak

243c0f18d[1] allowed the logger's progress bar to display during repl
builds, but startProgressBar() re-creates the entire logger from
scratch, discarding the value of printBuildLogs (and leaking the
previous logger). In this commit, we instead call logger->pause() and
logger->resume(), and in logger->pause(), we manually reset the
activities and stored values in the progress bar's state, so stuff from
multiple builds don't leak over into following ones.

[1]: 243c0f18da

Change-Id: Ie734d1f638d45759d232805d7e3c2005f7dea483
This commit is contained in:
Qyriad 2024-06-24 16:53:12 -06:00
parent d86009bd76
commit b178ccaf0a

View file

@ -300,7 +300,7 @@ ReplExitStatus NixRepl::mainLoop()
/* Stop the progress bar because it interferes with the display of
the repl. */
stopProgressBar();
logger->pause();
std::string input;
@ -684,9 +684,22 @@ ProcessLineResult NixRepl::processLine(std::string line)
// TODO: this only shows a progress bar for explicitly initiated builds,
// not eval-time fetching or builds performed for IFD.
// But we can't just show it everywhere, since that would erase partial output from evaluation.
startProgressBar();
logger->resume();
Finally stopLogger([&]() {
stopProgressBar();
logger->pause();
if (auto * progressBar = dynamic_cast<ProgressBar *>(logger)) {
auto state(progressBar->state_.lock());
bool const prevActive = state->active;
bool const prevPaused = state->paused;
bool const prevHaveUpdate = state->haveUpdate;
// HACK: reset the state, except for those three booleans, so the
// stats of multiple builds in the same repl session don't mingle.
*state = ProgressBar::State{
.active = prevActive,
.paused = prevPaused,
.haveUpdate = prevHaveUpdate,
};
}
});
state->store->buildPaths({