VcsBase: Introduce vcsExecWithHandler()

Before, vcsExec() returned already started VcsCommand.
Later, callers of vcsExec() were establishing connections
to the retured VcsCommand::done() signal. However, when
process fails to start (e.g. because of non-existing
executable), the done() signal may be emitted synchonously
from inside VcsCommand::start(). In this scenario
callers of VcsCommand could miss the emission of done()
signal and connect to already finished command.

Instead, provide a vcsExecWithHandler() function which
takes a handler to be called when command finished.
In addition it takes the context object, too.
Don't return VcsCommand from vcsExec() anymore.

Change-Id: I2fb5fbe5d27632ea039c650d37e5d7d1b60cebc0
Reviewed-by: Orgad Shaneh <orgads@gmail.com>
This commit is contained in:
Jarek Kobus
2022-12-08 18:50:54 +01:00
parent c08317b5a6
commit 287a7c9268
11 changed files with 193 additions and 167 deletions

View File

@@ -159,18 +159,37 @@ void VcsBaseClientImpl::annotateRevisionRequested(const FilePath &workingDirecto
annotate(workingDirectory, file, changeCopy, line);
}
VcsCommand *VcsBaseClientImpl::vcsExec(const FilePath &workingDirectory,
const QStringList &arguments,
VcsBaseEditorWidget *editor, bool useOutputToWindow,
RunFlags additionalFlags) const
void VcsBaseClientImpl::vcsExecWithHandler(const FilePath &workingDirectory,
const QStringList &arguments,
const QObject *context,
const CommandHandler &handler,
RunFlags additionalFlags,
bool useOutputToWindow) const
{
VcsCommand *command = createCommand(workingDirectory, nullptr,
useOutputToWindow ? VcsWindowOutputBind : NoOutputBind);
command->addFlags(additionalFlags);
command->addJob({vcsBinary(), arguments}, vcsTimeoutS());
if (handler) {
connect(command, &VcsCommand::done, context, [command, handler] {
handler(CommandResult(*command));
});
}
command->start();
}
void VcsBaseClientImpl::vcsExec(const FilePath &workingDirectory,
const QStringList &arguments,
VcsBaseEditorWidget *editor, bool useOutputToWindow,
RunFlags additionalFlags) const
{
VcsCommand *command = createCommand(workingDirectory, editor,
useOutputToWindow ? VcsWindowOutputBind : NoOutputBind);
command->addFlags(additionalFlags);
if (editor)
command->setCodec(editor->codec());
enqueueJob(command, arguments);
return command;
command->addJob({vcsBinary(), arguments}, vcsTimeoutS());
command->start();
}
int VcsBaseClientImpl::vcsTimeoutS() const