1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2025-06-25 02:21:16 +02:00

refactor: RAII logger suspension

(cherry picked from commit 30694b5d8a)
This commit is contained in:
Robert Hensing 2025-03-04 19:10:33 +01:00 committed by Mergify
parent 375df6c086
commit ac3fc8876c
7 changed files with 46 additions and 35 deletions

View file

@ -102,8 +102,7 @@ struct NixRepl
unsigned int maxDepth = std::numeric_limits<unsigned int>::max())
{
// Hide the progress bar during printing because it might interfere
logger->pause();
Finally resumeLoggerDefer([]() { logger->resume(); });
auto suspension = logger->suspend();
::nix::printValue(*state, str, v, PrintOptions {
.ansiColors = true,
.force = true,
@ -180,18 +179,20 @@ ReplExitStatus NixRepl::mainLoop()
while (true) {
// Hide the progress bar while waiting for user input, so that it won't interfere.
logger->pause();
// When continuing input from previous lines, don't print a prompt, just align to the same
// number of chars as the prompt.
if (!interacter->getLine(input, input.empty() ? ReplPromptType::ReplPrompt : ReplPromptType::ContinuationPrompt)) {
// Ctrl-D should exit the debugger.
state->debugStop = false;
logger->cout("");
// TODO: Should Ctrl-D exit just the current debugger session or
// the entire program?
return ReplExitStatus::QuitAll;
{
auto suspension = logger->suspend();
// When continuing input from previous lines, don't print a prompt, just align to the same
// number of chars as the prompt.
if (!interacter->getLine(input, input.empty() ? ReplPromptType::ReplPrompt : ReplPromptType::ContinuationPrompt)) {
// Ctrl-D should exit the debugger.
state->debugStop = false;
logger->cout("");
// TODO: Should Ctrl-D exit just the current debugger session or
// the entire program?
return ReplExitStatus::QuitAll;
}
// `suspension` resumes the logger
}
logger->resume();
try {
switch (processLine(input)) {
case ProcessLineResult::Quit:
@ -694,10 +695,9 @@ ProcessLineResult NixRepl::processLine(std::string line)
} else {
Value v;
evalString(line, v);
logger->pause();
auto suspension = logger->suspend();
printValue(std::cout, v, 1);
std::cout << std::endl;
logger->resume();
}
}

View file

@ -351,8 +351,7 @@ struct GitInputScheme : InputScheme
if (commitMsg) {
// Pause the logger to allow for user input (such as a gpg passphrase) in `git commit`
logger->pause();
Finally restoreLogger([]() { logger->resume(); });
auto suspension = logger->suspend();
runProgram("git", true,
{ "-C", repoPath->string(), "--git-dir", repoInfo.gitDir, "commit", std::string(path.rel()), "-F", "-" },
*commitMsg);

View file

@ -117,10 +117,10 @@ std::unique_ptr<SSHMaster::Connection> SSHMaster::startCommand(
ProcessOptions options;
options.dieWithParent = false;
std::unique_ptr<Logger::Suspension> loggerSuspension;
if (!fakeSSH && !useMaster) {
logger->pause();
loggerSuspension = std::make_unique<Logger::Suspension>(logger->suspend());
}
Finally cleanup = [&]() { logger->resume(); };
conn->sshPid = startProcess([&]() {
restoreProcessContext();
@ -199,8 +199,7 @@ Path SSHMaster::startMaster()
ProcessOptions options;
options.dieWithParent = false;
logger->pause();
Finally cleanup = [&]() { logger->resume(); };
auto suspension = logger->suspend();
if (isMasterRunning())
return state->socketPath;

View file

@ -43,6 +43,19 @@ void Logger::writeToStdout(std::string_view s)
writeFull(standard_out, "\n");
}
Logger::Suspension Logger::suspend()
{
pause();
return Suspension { ._finalize = {[this](){this->resume();}} };
}
std::optional<Logger::Suspension> Logger::suspendIf(bool cond)
{
if (cond)
return suspend();
return {};
}
class SimpleLogger : public Logger
{
public:

View file

@ -4,6 +4,7 @@
#include "error.hh"
#include "config.hh"
#include "file-descriptor.hh"
#include "finally.hh"
#include <nlohmann/json_fwd.hpp>
@ -75,6 +76,17 @@ public:
virtual void stop() { };
/**
* Guard object to resume the logger when done.
*/
struct Suspension {
Finally<std::function<void()>> _finalize;
};
Suspension suspend();
std::optional<Suspension> suspendIf(bool cond);
virtual void pause() { };
virtual void resume() { };

View file

@ -306,15 +306,7 @@ void runProgram2(const RunOptions & options)
// case), so we can't use it if we alter the environment
processOptions.allowVfork = !options.environment;
std::optional<Finally<std::function<void()>>> resumeLoggerDefer;
if (options.isInteractive) {
logger->pause();
resumeLoggerDefer.emplace(
[]() {
logger->resume();
}
);
}
auto suspension = logger->suspendIf(options.isInteractive);
/* Fork. */
Pid pid = startProcess([&] {

View file

@ -312,11 +312,7 @@ void runProgram2(const RunOptions & options)
// TODO: Implement shebang / program interpreter lookup on Windows
auto interpreter = getProgramInterpreter(realProgram);
std::optional<Finally<std::function<void()>>> resumeLoggerDefer;
if (options.isInteractive) {
logger->pause();
resumeLoggerDefer.emplace([]() { logger->resume(); });
}
auto suspension = logger->suspendIf(options.isInteractive);
Pid pid = spawnProcess(interpreter.has_value() ? *interpreter : realProgram, options, out, in);