mirror of
https://github.com/NixOS/nix
synced 2025-06-25 10:41:16 +02:00
refactor: RAII logger suspension
This commit is contained in:
parent
880489051a
commit
30694b5d8a
7 changed files with 46 additions and 35 deletions
|
@ -102,8 +102,7 @@ struct NixRepl
|
||||||
unsigned int maxDepth = std::numeric_limits<unsigned int>::max())
|
unsigned int maxDepth = std::numeric_limits<unsigned int>::max())
|
||||||
{
|
{
|
||||||
// Hide the progress bar during printing because it might interfere
|
// Hide the progress bar during printing because it might interfere
|
||||||
logger->pause();
|
auto suspension = logger->suspend();
|
||||||
Finally resumeLoggerDefer([]() { logger->resume(); });
|
|
||||||
::nix::printValue(*state, str, v, PrintOptions {
|
::nix::printValue(*state, str, v, PrintOptions {
|
||||||
.ansiColors = true,
|
.ansiColors = true,
|
||||||
.force = true,
|
.force = true,
|
||||||
|
@ -180,18 +179,20 @@ ReplExitStatus NixRepl::mainLoop()
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
// Hide the progress bar while waiting for user input, so that it won't interfere.
|
// 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
|
auto suspension = logger->suspend();
|
||||||
// number of chars as the prompt.
|
// When continuing input from previous lines, don't print a prompt, just align to the same
|
||||||
if (!interacter->getLine(input, input.empty() ? ReplPromptType::ReplPrompt : ReplPromptType::ContinuationPrompt)) {
|
// number of chars as the prompt.
|
||||||
// Ctrl-D should exit the debugger.
|
if (!interacter->getLine(input, input.empty() ? ReplPromptType::ReplPrompt : ReplPromptType::ContinuationPrompt)) {
|
||||||
state->debugStop = false;
|
// Ctrl-D should exit the debugger.
|
||||||
logger->cout("");
|
state->debugStop = false;
|
||||||
// TODO: Should Ctrl-D exit just the current debugger session or
|
logger->cout("");
|
||||||
// the entire program?
|
// TODO: Should Ctrl-D exit just the current debugger session or
|
||||||
return ReplExitStatus::QuitAll;
|
// the entire program?
|
||||||
|
return ReplExitStatus::QuitAll;
|
||||||
|
}
|
||||||
|
// `suspension` resumes the logger
|
||||||
}
|
}
|
||||||
logger->resume();
|
|
||||||
try {
|
try {
|
||||||
switch (processLine(input)) {
|
switch (processLine(input)) {
|
||||||
case ProcessLineResult::Quit:
|
case ProcessLineResult::Quit:
|
||||||
|
@ -694,10 +695,9 @@ ProcessLineResult NixRepl::processLine(std::string line)
|
||||||
} else {
|
} else {
|
||||||
Value v;
|
Value v;
|
||||||
evalString(line, v);
|
evalString(line, v);
|
||||||
logger->pause();
|
auto suspension = logger->suspend();
|
||||||
printValue(std::cout, v, 1);
|
printValue(std::cout, v, 1);
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
logger->resume();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -351,8 +351,7 @@ struct GitInputScheme : InputScheme
|
||||||
|
|
||||||
if (commitMsg) {
|
if (commitMsg) {
|
||||||
// Pause the logger to allow for user input (such as a gpg passphrase) in `git commit`
|
// Pause the logger to allow for user input (such as a gpg passphrase) in `git commit`
|
||||||
logger->pause();
|
auto suspension = logger->suspend();
|
||||||
Finally restoreLogger([]() { logger->resume(); });
|
|
||||||
runProgram("git", true,
|
runProgram("git", true,
|
||||||
{ "-C", repoPath->string(), "--git-dir", repoInfo.gitDir, "commit", std::string(path.rel()), "-F", "-" },
|
{ "-C", repoPath->string(), "--git-dir", repoInfo.gitDir, "commit", std::string(path.rel()), "-F", "-" },
|
||||||
*commitMsg);
|
*commitMsg);
|
||||||
|
|
|
@ -117,10 +117,10 @@ std::unique_ptr<SSHMaster::Connection> SSHMaster::startCommand(
|
||||||
ProcessOptions options;
|
ProcessOptions options;
|
||||||
options.dieWithParent = false;
|
options.dieWithParent = false;
|
||||||
|
|
||||||
|
std::unique_ptr<Logger::Suspension> loggerSuspension;
|
||||||
if (!fakeSSH && !useMaster) {
|
if (!fakeSSH && !useMaster) {
|
||||||
logger->pause();
|
loggerSuspension = std::make_unique<Logger::Suspension>(logger->suspend());
|
||||||
}
|
}
|
||||||
Finally cleanup = [&]() { logger->resume(); };
|
|
||||||
|
|
||||||
conn->sshPid = startProcess([&]() {
|
conn->sshPid = startProcess([&]() {
|
||||||
restoreProcessContext();
|
restoreProcessContext();
|
||||||
|
@ -199,8 +199,7 @@ Path SSHMaster::startMaster()
|
||||||
ProcessOptions options;
|
ProcessOptions options;
|
||||||
options.dieWithParent = false;
|
options.dieWithParent = false;
|
||||||
|
|
||||||
logger->pause();
|
auto suspension = logger->suspend();
|
||||||
Finally cleanup = [&]() { logger->resume(); };
|
|
||||||
|
|
||||||
if (isMasterRunning())
|
if (isMasterRunning())
|
||||||
return state->socketPath;
|
return state->socketPath;
|
||||||
|
|
|
@ -43,6 +43,19 @@ void Logger::writeToStdout(std::string_view s)
|
||||||
writeFull(standard_out, "\n");
|
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
|
class SimpleLogger : public Logger
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include "error.hh"
|
#include "error.hh"
|
||||||
#include "config.hh"
|
#include "config.hh"
|
||||||
#include "file-descriptor.hh"
|
#include "file-descriptor.hh"
|
||||||
|
#include "finally.hh"
|
||||||
|
|
||||||
#include <nlohmann/json_fwd.hpp>
|
#include <nlohmann/json_fwd.hpp>
|
||||||
|
|
||||||
|
@ -75,6 +76,17 @@ public:
|
||||||
|
|
||||||
virtual void stop() { };
|
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 pause() { };
|
||||||
virtual void resume() { };
|
virtual void resume() { };
|
||||||
|
|
||||||
|
|
|
@ -306,15 +306,7 @@ void runProgram2(const RunOptions & options)
|
||||||
// case), so we can't use it if we alter the environment
|
// case), so we can't use it if we alter the environment
|
||||||
processOptions.allowVfork = !options.environment;
|
processOptions.allowVfork = !options.environment;
|
||||||
|
|
||||||
std::optional<Finally<std::function<void()>>> resumeLoggerDefer;
|
auto suspension = logger->suspendIf(options.isInteractive);
|
||||||
if (options.isInteractive) {
|
|
||||||
logger->pause();
|
|
||||||
resumeLoggerDefer.emplace(
|
|
||||||
[]() {
|
|
||||||
logger->resume();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Fork. */
|
/* Fork. */
|
||||||
Pid pid = startProcess([&] {
|
Pid pid = startProcess([&] {
|
||||||
|
|
|
@ -312,11 +312,7 @@ void runProgram2(const RunOptions & options)
|
||||||
// TODO: Implement shebang / program interpreter lookup on Windows
|
// TODO: Implement shebang / program interpreter lookup on Windows
|
||||||
auto interpreter = getProgramInterpreter(realProgram);
|
auto interpreter = getProgramInterpreter(realProgram);
|
||||||
|
|
||||||
std::optional<Finally<std::function<void()>>> resumeLoggerDefer;
|
auto suspension = logger->suspendIf(options.isInteractive);
|
||||||
if (options.isInteractive) {
|
|
||||||
logger->pause();
|
|
||||||
resumeLoggerDefer.emplace([]() { logger->resume(); });
|
|
||||||
}
|
|
||||||
|
|
||||||
Pid pid = spawnProcess(interpreter.has_value() ? *interpreter : realProgram, options, out, in);
|
Pid pid = spawnProcess(interpreter.has_value() ? *interpreter : realProgram, options, out, in);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue