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 <orgads@gmail.com>
This commit is contained in:
Jarek Kobus
2022-07-14 11:00:00 +02:00
parent a1588918b3
commit a640a6ae8c
3 changed files with 54 additions and 47 deletions

View File

@@ -162,6 +162,11 @@ const FilePath &ShellCommand::defaultWorkingDirectory() const
return d->m_defaultWorkingDirectory; return d->m_defaultWorkingDirectory;
} }
Environment ShellCommand::environment() const
{
return d->m_environment;
}
void ShellCommand::setEnvironment(const Environment &env) void ShellCommand::setEnvironment(const Environment &env)
{ {
d->m_environment = env; d->m_environment = env;

View File

@@ -68,7 +68,7 @@ private:
friend class ShellCommand; friend class ShellCommand;
}; };
class QTCREATOR_UTILS_EXPORT ShellCommand : public QObject class QTCREATOR_UTILS_EXPORT ShellCommand final : public QObject
{ {
Q_OBJECT Q_OBJECT
@@ -98,6 +98,11 @@ public:
QString displayName() const; QString displayName() const;
void setDisplayName(const QString &name); void setDisplayName(const QString &name);
const FilePath &defaultWorkingDirectory() const;
Environment environment() const;
void setEnvironment(const Environment &env);
void addJob(const CommandLine &command, void addJob(const CommandLine &command,
const FilePath &workingDirectory = {}, const FilePath &workingDirectory = {},
const ExitCodeInterpreter &interpreter = {}); const ExitCodeInterpreter &interpreter = {});
@@ -107,8 +112,6 @@ public:
void execute(); // Execute tasks asynchronously! void execute(); // Execute tasks asynchronously!
void abort(); void abort();
const FilePath &defaultWorkingDirectory() const;
int defaultTimeoutS() const; int defaultTimeoutS() const;
void setDefaultTimeoutS(int timeout); void setDefaultTimeoutS(int timeout);
@@ -133,6 +136,9 @@ public:
void cancel(); void cancel();
void setDisableUnixTerminal();
int timeoutS() const;
signals: signals:
void stdOutText(const QString &); void stdOutText(const QString &);
void stdErrText(const QString &); void stdErrText(const QString &);
@@ -151,11 +157,6 @@ signals:
void executedAsync(const QFuture<void> &future); void executedAsync(const QFuture<void> &future);
void runCommandFinished(const Utils::FilePath &workingDirectory); void runCommandFinished(const Utils::FilePath &workingDirectory);
protected:
void setEnvironment(const Environment &env);
void setDisableUnixTerminal();
int timeoutS() const;
private: private:
FilePath workDirectory(const FilePath &wd) const; FilePath workDirectory(const FilePath &wd) const;
void run(QFutureInterface<void> &future); void run(QFutureInterface<void> &future);

View File

@@ -77,62 +77,60 @@ static IEditor *locateEditor(const char *property, const QString &entry)
namespace VcsBase { namespace VcsBase {
class VcsCommand : public ShellCommand class VcsCommandDecorator : public QObject
{ {
public: public:
VcsCommand(const FilePath &defaultWorkingDirectory, const Environment &environment); VcsCommandDecorator(ShellCommand *command);
private: private:
void addTask(const QFuture<void> &future); void addTask(const QFuture<void> &future);
void postRunCommand(const Utils::FilePath &workDirectory); void postRunCommand(const FilePath &workingDirectory);
ShellCommand *m_command;
}; };
VcsCommand::VcsCommand(const FilePath &workingDirectory, const Environment &environment) VcsCommandDecorator::VcsCommandDecorator(ShellCommand *command)
: ShellCommand(workingDirectory, environment) : QObject(command)
, m_command(command)
{ {
Environment env = environment; Environment env = m_command->environment();
VcsBase::setProcessEnvironment(&env); VcsBase::setProcessEnvironment(&env);
setEnvironment(env); m_command->setEnvironment(env);
VcsOutputWindow::setRepository(workingDirectory.toString()); VcsOutputWindow::setRepository(m_command->defaultWorkingDirectory().toString());
setDisableUnixTerminal(); m_command->setDisableUnixTerminal();
connect(m_command, &ShellCommand::started, this, [this] {
connect(this, &ShellCommand::started, this, [this] { if (m_command->flags() & ShellCommand::ExpectRepoChanges)
if (flags() & ExpectRepoChanges)
GlobalFileChangeBlocker::instance()->forceBlocked(true); GlobalFileChangeBlocker::instance()->forceBlocked(true);
}); });
connect(this, &ShellCommand::finished, this, [this] { connect(m_command, &ShellCommand::finished, this, [this] {
if (flags() & ExpectRepoChanges) if (m_command->flags() & ShellCommand::ExpectRepoChanges)
GlobalFileChangeBlocker::instance()->forceBlocked(false); GlobalFileChangeBlocker::instance()->forceBlocked(false);
}); });
VcsOutputWindow *outputWindow = VcsOutputWindow::instance(); 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); outputWindow->append(t);
}); });
connect(this, &ShellCommand::appendSilently, outputWindow, &VcsOutputWindow::appendSilently); connect(m_command, &ShellCommand::appendSilently, outputWindow, &VcsOutputWindow::appendSilently);
connect(this, &ShellCommand::appendError, outputWindow, &VcsOutputWindow::appendError); connect(m_command, &ShellCommand::appendError, outputWindow, &VcsOutputWindow::appendError);
connect(this, &ShellCommand::appendCommand, outputWindow, &VcsOutputWindow::appendCommand); connect(m_command, &ShellCommand::appendCommand, outputWindow, &VcsOutputWindow::appendCommand);
connect(this, &ShellCommand::appendMessage, outputWindow, &VcsOutputWindow::appendMessage); connect(m_command, &ShellCommand::appendMessage, outputWindow, &VcsOutputWindow::appendMessage);
connect(m_command, &ShellCommand::executedAsync, this, &VcsCommandDecorator::addTask);
connect(this, &ShellCommand::executedAsync, this, &VcsCommand::addTask); const auto connection = connect(m_command, &ShellCommand::runCommandFinished,
const auto connection = connect(this, &ShellCommand::runCommandFinished, this, &VcsCommandDecorator::postRunCommand);
this, &VcsCommand::postRunCommand); connect(ICore::instance(), &ICore::coreAboutToClose, this, [connection] {
connect(ICore::instance(), &ICore::coreAboutToClose, this, [this, connection] {
disconnect(connection); disconnect(connection);
abort(); abort();
}); });}
}
void VcsCommand::addTask(const QFuture<void> &future) void VcsCommandDecorator::addTask(const QFuture<void> &future)
{ {
if ((flags() & SuppressCommandLogging)) if ((m_command->flags() & ShellCommand::SuppressCommandLogging))
return; return;
const QString name = displayName(); const QString name = m_command->displayName();
const auto id = Id::fromString(name + QLatin1String(".action")); const auto id = Id::fromString(name + QLatin1String(".action"));
if (hasProgressParser()) { if (m_command->hasProgressParser()) {
ProgressManager::addTask(future, name, id); ProgressManager::addTask(future, name, id);
} else { } else {
// add a timed tasked based on timeout // add a timed tasked based on timeout
@@ -146,22 +144,21 @@ void VcsCommand::addTask(const QFuture<void> &future)
watcher->deleteLater(); watcher->deleteLater();
}); });
watcher->setFuture(future); 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); 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; return;
// TODO tell the document manager that the directory now received all expected changes // TODO tell the document manager that the directory now received all expected changes
// Core::DocumentManager::unexpectDirectoryChange(d->m_workingDirectory); // Core::DocumentManager::unexpectDirectoryChange(d->m_workingDirectory);
VcsManager::emitRepositoryChanged(workingDirectory); VcsManager::emitRepositoryChanged(workingDirectory);
} }
VcsBaseClientImpl::VcsBaseClientImpl(VcsBaseSettings *baseSettings) VcsBaseClientImpl::VcsBaseClientImpl(VcsBaseSettings *baseSettings)
: m_baseSettings(baseSettings) : m_baseSettings(baseSettings)
{ {
@@ -257,7 +254,8 @@ void VcsBaseClientImpl::vcsFullySynchronousExec(QtcProcess &proc,
const FilePath &workingDir, const CommandLine &cmdLine, const FilePath &workingDir, const CommandLine &cmdLine,
unsigned flags, int timeoutS, QTextCodec *codec) const unsigned flags, int timeoutS, QTextCodec *codec) const
{ {
VcsCommand command(workingDir, processEnvironment()); ShellCommand command(workingDir, processEnvironment());
new VcsCommandDecorator(&command);
command.addFlags(flags); command.addFlags(flags);
if (codec) if (codec)
command.setCodec(codec); command.setCodec(codec);
@@ -305,7 +303,8 @@ void VcsBaseClientImpl::vcsSynchronousExec(QtcProcess &proc,
QTextCodec *outputCodec) const QTextCodec *outputCodec) const
{ {
Environment env = processEnvironment(); 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()); proc.setTimeoutS(vcsTimeoutS());
command.addFlags(flags); command.addFlags(flags);
command.setCodec(outputCodec); command.setCodec(outputCodec);
@@ -320,7 +319,9 @@ int VcsBaseClientImpl::vcsTimeoutS() const
ShellCommand *VcsBaseClientImpl::createVcsCommand(const FilePath &defaultWorkingDir, ShellCommand *VcsBaseClientImpl::createVcsCommand(const FilePath &defaultWorkingDir,
const Environment &environment) 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, VcsBaseEditorWidget *VcsBaseClientImpl::createVcsEditor(Id kind, QString title,