From a640a6ae8cb1b80f835655a0def3701f3e133038 Mon Sep 17 00:00:00 2001 From: Jarek Kobus Date: Thu, 14 Jul 2022 11:00:00 +0200 Subject: [PATCH] VcsCommand: Don't derive from ShellCommand Transform VcsCommand into VcsCommandDecorator and attach it to ShellCommand. There is no need to derive from ShellCommand anymore. Use ShellCommand's public API to setup vcs command via VcsCommandDecorator. Make ShellCommand final. Change-Id: I39e3699c80a9e108bcaeef7fb02214e2cc0d0dee Reviewed-by: Orgad Shaneh --- src/libs/utils/shellcommand.cpp | 5 ++ src/libs/utils/shellcommand.h | 17 +++--- src/plugins/vcsbase/vcsbaseclient.cpp | 79 ++++++++++++++------------- 3 files changed, 54 insertions(+), 47 deletions(-) diff --git a/src/libs/utils/shellcommand.cpp b/src/libs/utils/shellcommand.cpp index a05d1a5cdd4..04ff749c1fa 100644 --- a/src/libs/utils/shellcommand.cpp +++ b/src/libs/utils/shellcommand.cpp @@ -162,6 +162,11 @@ const FilePath &ShellCommand::defaultWorkingDirectory() const return d->m_defaultWorkingDirectory; } +Environment ShellCommand::environment() const +{ + return d->m_environment; +} + void ShellCommand::setEnvironment(const Environment &env) { d->m_environment = env; diff --git a/src/libs/utils/shellcommand.h b/src/libs/utils/shellcommand.h index 64c319c8142..5f347dd38ab 100644 --- a/src/libs/utils/shellcommand.h +++ b/src/libs/utils/shellcommand.h @@ -68,7 +68,7 @@ private: friend class ShellCommand; }; -class QTCREATOR_UTILS_EXPORT ShellCommand : public QObject +class QTCREATOR_UTILS_EXPORT ShellCommand final : public QObject { Q_OBJECT @@ -98,6 +98,11 @@ public: QString displayName() const; void setDisplayName(const QString &name); + const FilePath &defaultWorkingDirectory() const; + + Environment environment() const; + void setEnvironment(const Environment &env); + void addJob(const CommandLine &command, const FilePath &workingDirectory = {}, const ExitCodeInterpreter &interpreter = {}); @@ -107,8 +112,6 @@ public: void execute(); // Execute tasks asynchronously! void abort(); - const FilePath &defaultWorkingDirectory() const; - int defaultTimeoutS() const; void setDefaultTimeoutS(int timeout); @@ -133,6 +136,9 @@ public: void cancel(); + void setDisableUnixTerminal(); + int timeoutS() const; + signals: void stdOutText(const QString &); void stdErrText(const QString &); @@ -151,11 +157,6 @@ signals: void executedAsync(const QFuture &future); void runCommandFinished(const Utils::FilePath &workingDirectory); -protected: - void setEnvironment(const Environment &env); - void setDisableUnixTerminal(); - int timeoutS() const; - private: FilePath workDirectory(const FilePath &wd) const; void run(QFutureInterface &future); diff --git a/src/plugins/vcsbase/vcsbaseclient.cpp b/src/plugins/vcsbase/vcsbaseclient.cpp index ea3e4fabd0f..591da5a1226 100644 --- a/src/plugins/vcsbase/vcsbaseclient.cpp +++ b/src/plugins/vcsbase/vcsbaseclient.cpp @@ -77,62 +77,60 @@ static IEditor *locateEditor(const char *property, const QString &entry) namespace VcsBase { -class VcsCommand : public ShellCommand +class VcsCommandDecorator : public QObject { public: - VcsCommand(const FilePath &defaultWorkingDirectory, const Environment &environment); + VcsCommandDecorator(ShellCommand *command); private: void addTask(const QFuture &future); - void postRunCommand(const Utils::FilePath &workDirectory); + void postRunCommand(const FilePath &workingDirectory); + + ShellCommand *m_command; }; -VcsCommand::VcsCommand(const FilePath &workingDirectory, const Environment &environment) - : ShellCommand(workingDirectory, environment) +VcsCommandDecorator::VcsCommandDecorator(ShellCommand *command) + : QObject(command) + , m_command(command) { - Environment env = environment; + Environment env = m_command->environment(); VcsBase::setProcessEnvironment(&env); - setEnvironment(env); + m_command->setEnvironment(env); - VcsOutputWindow::setRepository(workingDirectory.toString()); - setDisableUnixTerminal(); - - connect(this, &ShellCommand::started, this, [this] { - if (flags() & ExpectRepoChanges) + VcsOutputWindow::setRepository(m_command->defaultWorkingDirectory().toString()); + m_command->setDisableUnixTerminal(); + connect(m_command, &ShellCommand::started, this, [this] { + if (m_command->flags() & ShellCommand::ExpectRepoChanges) GlobalFileChangeBlocker::instance()->forceBlocked(true); }); - connect(this, &ShellCommand::finished, this, [this] { - if (flags() & ExpectRepoChanges) + connect(m_command, &ShellCommand::finished, this, [this] { + if (m_command->flags() & ShellCommand::ExpectRepoChanges) GlobalFileChangeBlocker::instance()->forceBlocked(false); }); - VcsOutputWindow *outputWindow = VcsOutputWindow::instance(); - connect(this, &ShellCommand::append, outputWindow, [outputWindow](const QString &t) { + connect(m_command, &ShellCommand::append, outputWindow, [outputWindow](const QString &t) { outputWindow->append(t); }); - connect(this, &ShellCommand::appendSilently, outputWindow, &VcsOutputWindow::appendSilently); - connect(this, &ShellCommand::appendError, outputWindow, &VcsOutputWindow::appendError); - connect(this, &ShellCommand::appendCommand, outputWindow, &VcsOutputWindow::appendCommand); - connect(this, &ShellCommand::appendMessage, outputWindow, &VcsOutputWindow::appendMessage); - - connect(this, &ShellCommand::executedAsync, this, &VcsCommand::addTask); - const auto connection = connect(this, &ShellCommand::runCommandFinished, - this, &VcsCommand::postRunCommand); - - connect(ICore::instance(), &ICore::coreAboutToClose, this, [this, connection] { + connect(m_command, &ShellCommand::appendSilently, outputWindow, &VcsOutputWindow::appendSilently); + connect(m_command, &ShellCommand::appendError, outputWindow, &VcsOutputWindow::appendError); + connect(m_command, &ShellCommand::appendCommand, outputWindow, &VcsOutputWindow::appendCommand); + connect(m_command, &ShellCommand::appendMessage, outputWindow, &VcsOutputWindow::appendMessage); + connect(m_command, &ShellCommand::executedAsync, this, &VcsCommandDecorator::addTask); + const auto connection = connect(m_command, &ShellCommand::runCommandFinished, + this, &VcsCommandDecorator::postRunCommand); + connect(ICore::instance(), &ICore::coreAboutToClose, this, [connection] { disconnect(connection); abort(); - }); -} + });} -void VcsCommand::addTask(const QFuture &future) +void VcsCommandDecorator::addTask(const QFuture &future) { - if ((flags() & SuppressCommandLogging)) + if ((m_command->flags() & ShellCommand::SuppressCommandLogging)) return; - const QString name = displayName(); + const QString name = m_command->displayName(); const auto id = Id::fromString(name + QLatin1String(".action")); - if (hasProgressParser()) { + if (m_command->hasProgressParser()) { ProgressManager::addTask(future, name, id); } else { // add a timed tasked based on timeout @@ -146,22 +144,21 @@ void VcsCommand::addTask(const QFuture &future) watcher->deleteLater(); }); watcher->setFuture(future); - ProgressManager::addTimedTask(*fi, name, id, qMax(2, timeoutS() / 5)/*itsmagic*/); + ProgressManager::addTimedTask(*fi, name, id, qMax(2, m_command->timeoutS() / 5)); } Internal::VcsPlugin::addFuture(future); } -void VcsCommand::postRunCommand(const FilePath &workingDirectory) +void VcsCommandDecorator::postRunCommand(const FilePath &workingDirectory) { - if (!(flags() & ShellCommand::ExpectRepoChanges)) + if (!(m_command->flags() & ShellCommand::ExpectRepoChanges)) return; // TODO tell the document manager that the directory now received all expected changes // Core::DocumentManager::unexpectDirectoryChange(d->m_workingDirectory); VcsManager::emitRepositoryChanged(workingDirectory); } - VcsBaseClientImpl::VcsBaseClientImpl(VcsBaseSettings *baseSettings) : m_baseSettings(baseSettings) { @@ -257,7 +254,8 @@ void VcsBaseClientImpl::vcsFullySynchronousExec(QtcProcess &proc, const FilePath &workingDir, const CommandLine &cmdLine, unsigned flags, int timeoutS, QTextCodec *codec) const { - VcsCommand command(workingDir, processEnvironment()); + ShellCommand command(workingDir, processEnvironment()); + new VcsCommandDecorator(&command); command.addFlags(flags); if (codec) command.setCodec(codec); @@ -305,7 +303,8 @@ void VcsBaseClientImpl::vcsSynchronousExec(QtcProcess &proc, QTextCodec *outputCodec) const { Environment env = processEnvironment(); - VcsCommand command(workingDir, env.isValid() ? env : Environment::systemEnvironment()); + ShellCommand command(workingDir, env.isValid() ? env : Environment::systemEnvironment()); + new VcsCommandDecorator(&command); proc.setTimeoutS(vcsTimeoutS()); command.addFlags(flags); command.setCodec(outputCodec); @@ -320,7 +319,9 @@ int VcsBaseClientImpl::vcsTimeoutS() const ShellCommand *VcsBaseClientImpl::createVcsCommand(const FilePath &defaultWorkingDir, const Environment &environment) { - return new VcsCommand(defaultWorkingDir, environment); + ShellCommand *command = new ShellCommand(defaultWorkingDir, environment); + new VcsCommandDecorator(command); + return command; } VcsBaseEditorWidget *VcsBaseClientImpl::createVcsEditor(Id kind, QString title,