diff --git a/src/libs/utils/CMakeLists.txt b/src/libs/utils/CMakeLists.txt index 45551143ba3..30ed6647892 100644 --- a/src/libs/utils/CMakeLists.txt +++ b/src/libs/utils/CMakeLists.txt @@ -142,8 +142,6 @@ add_qtc_library(Utils settingsaccessor.cpp settingsaccessor.h settingsselector.cpp settingsselector.h settingsutils.h - shellcommand.cpp shellcommand.h - shellcommandpage.cpp shellcommandpage.h singleton.cpp singleton.h sizedarray.h smallstring.h diff --git a/src/libs/utils/qtcprocess.cpp b/src/libs/utils/qtcprocess.cpp index 440a4cf3f21..6b073dd3950 100644 --- a/src/libs/utils/qtcprocess.cpp +++ b/src/libs/utils/qtcprocess.cpp @@ -1707,7 +1707,7 @@ QString QtcProcess::stdOut() const QString QtcProcess::stdErr() const { // FIXME: The tighter check below is actually good theoretically, but currently - // ShellCommand::runFullySynchronous triggers it and disentangling there + // VcsCommand::runFullySynchronous triggers it and disentangling there // is not trivial. So weaken it a bit for now. //QTC_CHECK(d->m_stdErr.keepRawData); QTC_CHECK(d->m_stdErr.keepRawData || d->m_stdErr.rawData.isEmpty()); diff --git a/src/libs/utils/shellcommandpage.cpp b/src/libs/utils/shellcommandpage.cpp deleted file mode 100644 index 3d8e49225bc..00000000000 --- a/src/libs/utils/shellcommandpage.cpp +++ /dev/null @@ -1,154 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#include "shellcommandpage.h" -#include "shellcommand.h" -#include "outputformatter.h" -#include "qtcassert.h" -#include "theme/theme.h" - -#include -#include -#include -#include -#include - -/*! - \class Utils::ShellCommandPage - - \brief The ShellCommandPage implements a page showing the - progress of a \c ShellCommand. - - Turns complete when the command succeeds. -*/ - -namespace Utils { - -ShellCommandPage::ShellCommandPage(QWidget *parent) : - WizardPage(parent), - m_startedStatus(tr("Command started...")) -{ - resize(264, 200); - auto verticalLayout = new QVBoxLayout(this); - m_logPlainTextEdit = new QPlainTextEdit; - m_formatter = new OutputFormatter; - m_logPlainTextEdit->setReadOnly(true); - m_formatter->setPlainTextEdit(m_logPlainTextEdit); - - verticalLayout->addWidget(m_logPlainTextEdit); - - m_statusLabel = new QLabel; - verticalLayout->addWidget(m_statusLabel); - setTitle(tr("Run Command")); -} - -ShellCommandPage::~ShellCommandPage() -{ - QTC_ASSERT(m_state != Running, QApplication::restoreOverrideCursor()); - delete m_formatter; -} - -void ShellCommandPage::setStartedStatus(const QString &startedStatus) -{ - m_startedStatus = startedStatus; -} - -void ShellCommandPage::start(ShellCommand *command) -{ - if (!command) { - m_logPlainTextEdit->setPlainText(tr("No job running, please abort.")); - return; - } - - QTC_ASSERT(m_state != Running, return); - m_command = command; - command->setProgressiveOutput(true); - connect(command, &ShellCommand::stdOutText, this, [this](const QString &text) { - m_formatter->appendMessage(text, StdOutFormat); - }); - connect(command, &ShellCommand::stdErrText, this, [this](const QString &text) { - m_formatter->appendMessage(text, StdErrFormat); - }); - connect(command, &ShellCommand::finished, this, &ShellCommandPage::slotFinished); - QApplication::setOverrideCursor(Qt::WaitCursor); - m_logPlainTextEdit->clear(); - m_overwriteOutput = false; - m_statusLabel->setText(m_startedStatus); - m_statusLabel->setPalette(QPalette()); - m_state = Running; - command->execute(); - - wizard()->button(QWizard::BackButton)->setEnabled(false); -} - -void ShellCommandPage::slotFinished(bool success, const QVariant &) -{ - QTC_ASSERT(m_state == Running, return); - - QString message; - QPalette palette; - - if (success) { - m_state = Succeeded; - message = tr("Succeeded."); - palette.setColor(QPalette::WindowText, creatorTheme()->color(Theme::TextColorNormal).name()); - } else { - m_state = Failed; - message = tr("Failed."); - palette.setColor(QPalette::WindowText, creatorTheme()->color(Theme::TextColorError).name()); - } - - m_statusLabel->setText(message); - m_statusLabel->setPalette(palette); - - QApplication::restoreOverrideCursor(); - wizard()->button(QWizard::BackButton)->setEnabled(true); - - if (success) - emit completeChanged(); - emit finished(success); -} - -void ShellCommandPage::terminate() -{ - if (m_command) - m_command->cancel(); -} - -bool ShellCommandPage::handleReject() -{ - if (!isRunning()) - return false; - - terminate(); - return true; -} - -bool ShellCommandPage::isComplete() const -{ - return m_state == Succeeded; -} - -} // namespace Utils diff --git a/src/libs/utils/shellcommandpage.h b/src/libs/utils/shellcommandpage.h deleted file mode 100644 index 40dd07743fb..00000000000 --- a/src/libs/utils/shellcommandpage.h +++ /dev/null @@ -1,78 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of Qt Creator. -** -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 as published by the Free Software -** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -****************************************************************************/ - -#pragma once - -#include "utils_global.h" - -#include "wizardpage.h" - -QT_BEGIN_NAMESPACE -class QPlainTextEdit; -class QLabel; -QT_END_NAMESPACE - -namespace Utils { -class OutputFormatter; -class ShellCommand; - -class QTCREATOR_UTILS_EXPORT ShellCommandPage : public WizardPage -{ - Q_OBJECT - -public: - enum State { Idle, Running, Failed, Succeeded }; - - explicit ShellCommandPage(QWidget *parent = nullptr); - ~ShellCommandPage() override; - - void setStartedStatus(const QString &startedStatus); - void start(ShellCommand *command); - - bool isComplete() const override; - bool isRunning() const{ return m_state == Running; } - - void terminate(); - - bool handleReject() override; - -signals: - void finished(bool success); - -private: - void slotFinished(bool success, const QVariant &cookie); - - QPlainTextEdit *m_logPlainTextEdit; - OutputFormatter *m_formatter; - QLabel *m_statusLabel; - - ShellCommand *m_command = nullptr; - QString m_startedStatus; - bool m_overwriteOutput = false; - - State m_state = Idle; -}; - -} // namespace Utils diff --git a/src/libs/utils/utils.qbs b/src/libs/utils/utils.qbs index ad13b9bc0bc..4252ebae13a 100644 --- a/src/libs/utils/utils.qbs +++ b/src/libs/utils/utils.qbs @@ -269,10 +269,6 @@ Project { "settingsselector.cpp", "settingsselector.h", "settingsutils.h", - "shellcommand.cpp", - "shellcommand.h", - "shellcommandpage.cpp", - "shellcommandpage.h", "singleton.cpp", "singleton.h", "sizedarray.h", diff --git a/src/plugins/bazaar/bazaarclient.cpp b/src/plugins/bazaar/bazaarclient.cpp index 5dc14d9f64c..5409cef8dd1 100644 --- a/src/plugins/bazaar/bazaarclient.cpp +++ b/src/plugins/bazaar/bazaarclient.cpp @@ -27,11 +27,11 @@ #include "constants.h" #include -#include #include +#include +#include #include -#include #include #include diff --git a/src/plugins/bazaar/bazaarplugin.cpp b/src/plugins/bazaar/bazaarplugin.cpp index 8f0335d14ab..c83d5b40a1a 100644 --- a/src/plugins/bazaar/bazaarplugin.cpp +++ b/src/plugins/bazaar/bazaarplugin.cpp @@ -50,7 +50,6 @@ #include #include #include -#include #include #include @@ -60,6 +59,7 @@ #include #include #include +#include #include #include @@ -162,10 +162,10 @@ public: void vcsAnnotate(const Utils::FilePath &file, int line) final; void vcsDescribe(const Utils::FilePath &source, const QString &id) final { m_client.view(source.toString(), id); } - ShellCommand *createInitialCheckoutCommand(const QString &url, - const Utils::FilePath &baseDirectory, - const QString &localName, - const QStringList &extraArgs) final; + VcsCommand *createInitialCheckoutCommand(const QString &url, + const Utils::FilePath &baseDirectory, + const QString &localName, + const QStringList &extraArgs) final; // To be connected to the VCSTask's success signal to emit the repository/ // files changed signals according to the variant's type: @@ -923,10 +923,10 @@ void BazaarPluginPrivate::vcsAnnotate(const FilePath &file, int line) m_client.annotate(file.parentDir(), file.fileName(), QString(), line); } -ShellCommand *BazaarPluginPrivate::createInitialCheckoutCommand(const QString &url, - const FilePath &baseDirectory, - const QString &localName, - const QStringList &extraArgs) +VcsCommand *BazaarPluginPrivate::createInitialCheckoutCommand(const QString &url, + const FilePath &baseDirectory, + const QString &localName, + const QStringList &extraArgs) { QStringList args; args << m_client.vcsCommandString(BazaarClient::CloneCommand) diff --git a/src/plugins/clearcase/clearcaseplugin.cpp b/src/plugins/clearcase/clearcaseplugin.cpp index b75ac20cecf..5a8f5d72aad 100644 --- a/src/plugins/clearcase/clearcaseplugin.cpp +++ b/src/plugins/clearcase/clearcaseplugin.cpp @@ -62,7 +62,6 @@ #include #include #include -#include #include #include @@ -73,6 +72,7 @@ #include #include #include +#include #include #include @@ -128,8 +128,8 @@ static const char CMD_ID_UPDATE_VIEW[] = "ClearCase.UpdateView"; static const char CMD_ID_CHECKIN_ALL[] = "ClearCase.CheckInAll"; static const char CMD_ID_STATUS[] = "ClearCase.Status"; -const int s_silentRun = ShellCommand::NoOutput | ShellCommand::FullySynchronously; -const int s_verboseRun = ShellCommand::ShowStdOut | ShellCommand::FullySynchronously; +const int s_silentRun = VcsCommand::NoOutput | VcsCommand::FullySynchronously; +const int s_verboseRun = VcsCommand::ShowStdOut | VcsCommand::FullySynchronously; class ClearCaseResponse { @@ -1538,7 +1538,7 @@ void ClearCasePluginPrivate::ccUpdate(const FilePath &workingDir, const QStringL if (!relativePaths.isEmpty()) args.append(relativePaths); const ClearCaseResponse response = - runCleartool(workingDir, args, m_settings.longTimeOutS(), ShellCommand::ShowStdOut); + runCleartool(workingDir, args, m_settings.longTimeOutS(), VcsCommand::ShowStdOut); if (!response.error) emit repositoryChanged(workingDir); } @@ -1793,7 +1793,7 @@ bool ClearCasePluginPrivate::vcsOpen(const FilePath &workingDir, const QString & } args << file; ClearCaseResponse response = runCleartool(topLevel, args, m_settings.timeOutS, - s_verboseRun | ShellCommand::SuppressStdErr); + s_verboseRun | VcsCommand::SuppressStdErr); if (response.error) { if (response.stdErr.contains(QLatin1String("Versions other than the selected version"))) { VersionSelector selector(file, response.stdErr); @@ -1833,7 +1833,7 @@ bool ClearCasePluginPrivate::vcsSetActivity(const FilePath &workingDir, const QS QStringList args; args << QLatin1String("setactivity") << activity; const ClearCaseResponse actResponse = - runCleartool(workingDir, args, m_settings.timeOutS, ShellCommand::ShowStdOut); + runCleartool(workingDir, args, m_settings.timeOutS, VcsCommand::ShowStdOut); if (actResponse.error) { QMessageBox::warning(ICore::dialogParent(), title, tr("Set current activity failed: %1").arg(actResponse.message), QMessageBox::Ok); @@ -1880,7 +1880,7 @@ bool ClearCasePluginPrivate::vcsCheckIn(const FilePath &messageFile, const QStri blockers.append(fcb); } const ClearCaseResponse response = - runCleartool(m_checkInView, args, m_settings.longTimeOutS(), ShellCommand::ShowStdOut); + runCleartool(m_checkInView, args, m_settings.longTimeOutS(), VcsCommand::ShowStdOut); const QRegularExpression checkedIn("Checked in \\\"([^\"]*)\\\""); QRegularExpressionMatch match = checkedIn.match(response.stdOut); bool anySucceeded = false; diff --git a/src/plugins/coreplugin/iversioncontrol.cpp b/src/plugins/coreplugin/iversioncontrol.cpp index 2be687f3ef9..2d06da8bc29 100644 --- a/src/plugins/coreplugin/iversioncontrol.cpp +++ b/src/plugins/coreplugin/iversioncontrol.cpp @@ -88,7 +88,7 @@ FilePaths IVersionControl::additionalToolsPath() const return {}; } -ShellCommand *IVersionControl::createInitialCheckoutCommand(const QString &url, +VcsBase::VcsCommand *IVersionControl::createInitialCheckoutCommand(const QString &url, const Utils::FilePath &baseDirectory, const QString &localName, const QStringList &extraArgs) diff --git a/src/plugins/coreplugin/iversioncontrol.h b/src/plugins/coreplugin/iversioncontrol.h index ac9681bfb7d..baff3bc809d 100644 --- a/src/plugins/coreplugin/iversioncontrol.h +++ b/src/plugins/coreplugin/iversioncontrol.h @@ -38,7 +38,7 @@ QT_FORWARD_DECLARE_CLASS(QMenu); -namespace Utils { class ShellCommand; } +namespace VcsBase { class VcsCommand; } namespace Core { @@ -224,12 +224,12 @@ public: virtual Utils::FilePaths additionalToolsPath() const; /*! - * Return a ShellCommand capable of checking out \a url into \a baseDirectory, where + * Return a VcsCommand capable of checking out \a url into \a baseDirectory, where * a new subdirectory with \a localName will be created. * * \a extraArgs are passed on to the command being run. */ - virtual Utils::ShellCommand *createInitialCheckoutCommand(const QString &url, + virtual VcsBase::VcsCommand *createInitialCheckoutCommand(const QString &url, const Utils::FilePath &baseDirectory, const QString &localName, const QStringList &extraArgs); diff --git a/src/plugins/cvs/cvsplugin.cpp b/src/plugins/cvs/cvsplugin.cpp index 2ee2e64ec79..a155af8a05b 100644 --- a/src/plugins/cvs/cvsplugin.cpp +++ b/src/plugins/cvs/cvsplugin.cpp @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -58,7 +59,6 @@ #include #include #include -#include #include #include @@ -113,7 +113,7 @@ const char CVS_SUBMIT_MIMETYPE[] = "text/vnd.qtcreator.cvs.submit"; const char CVSCOMMITEDITOR_ID[] = "CVS Commit Editor"; const char CVSCOMMITEDITOR_DISPLAY_NAME[] = QT_TRANSLATE_NOOP("VCS", "CVS Commit Editor"); -const int s_defaultFlags = ShellCommand::SshPasswordPrompt | ShellCommand::ShowStdOut; +const int s_defaultFlags = VcsCommand::SshPasswordPrompt | VcsCommand::ShowStdOut; class CvsResponse { @@ -253,10 +253,10 @@ public: QString vcsOpenText() const final; - ShellCommand *createInitialCheckoutCommand(const QString &url, - const Utils::FilePath &baseDirectory, - const QString &localName, - const QStringList &extraArgs) final; + VcsCommand *createInitialCheckoutCommand(const QString &url, + const Utils::FilePath &baseDirectory, + const QString &localName, + const QStringList &extraArgs) final; /// @@ -474,10 +474,10 @@ QString CvsPluginPrivate::vcsOpenText() const return tr("&Edit"); } -ShellCommand *CvsPluginPrivate::createInitialCheckoutCommand(const QString &url, - const Utils::FilePath &baseDirectory, - const QString &localName, - const QStringList &extraArgs) +VcsCommand *CvsPluginPrivate::createInitialCheckoutCommand(const QString &url, + const Utils::FilePath &baseDirectory, + const QString &localName, + const QStringList &extraArgs) { QTC_ASSERT(localName == url, return nullptr); @@ -974,7 +974,7 @@ void CvsPluginPrivate::startCommit(const FilePath &workingDir, const QString &fi // where we are, so, have stdout/stderr channels merged. QStringList args = QStringList(QLatin1String("status")); const CvsResponse response = - runCvs(workingDir, args, m_settings.timeout.value(), ShellCommand::MergeOutputChannels); + runCvs(workingDir, args, m_settings.timeout.value(), VcsCommand::MergeOutputChannels); if (response.result != CvsResponse::Ok) return; // Get list of added/modified/deleted files and purge out undesired ones @@ -1058,7 +1058,7 @@ void CvsPluginPrivate::filelog(const FilePath &workingDir, args.append(file); const CvsResponse response = runCvs(workingDir, args, m_settings.timeout.value(), - ShellCommand::SshPasswordPrompt, codec); + VcsCommand::SshPasswordPrompt, codec); if (response.result != CvsResponse::Ok) return; @@ -1198,7 +1198,7 @@ void CvsPluginPrivate::annotate(const FilePath &workingDir, const QString &file, args << QLatin1String("-r") << revision; args << file; const CvsResponse response = runCvs(workingDir, args, m_settings.timeout.value(), - ShellCommand::SshPasswordPrompt, codec); + VcsCommand::SshPasswordPrompt, codec); if (response.result != CvsResponse::Ok) return; @@ -1300,7 +1300,7 @@ bool CvsPluginPrivate::describe(const FilePath &toplevel, const QString &file, c QStringList args; args << QLatin1String("log") << (QLatin1String("-r") + changeNr) << file; const CvsResponse logResponse = runCvs(toplevel, args, m_settings.timeout.value(), - ShellCommand::SshPasswordPrompt); + VcsCommand::SshPasswordPrompt); if (logResponse.result != CvsResponse::Ok) { *errorMessage = logResponse.message; return false; @@ -1322,7 +1322,7 @@ bool CvsPluginPrivate::describe(const FilePath &toplevel, const QString &file, c args << QLatin1String("log") << QLatin1String("-d") << (dateS + QLatin1Char('<') + nextDayS); const CvsResponse repoLogResponse = runCvs(toplevel, args, 10 * m_settings.timeout.value(), - ShellCommand::SshPasswordPrompt); + VcsCommand::SshPasswordPrompt); if (repoLogResponse.result != CvsResponse::Ok) { *errorMessage = repoLogResponse.message; return false; @@ -1359,7 +1359,7 @@ bool CvsPluginPrivate::describe(const FilePath &repositoryPath, QStringList args(QLatin1String("log")); args << (QLatin1String("-r") + it->revisions.front().revision) << it->file; const CvsResponse logResponse = runCvs(repositoryPath, args, m_settings.timeout.value(), - ShellCommand::SshPasswordPrompt); + VcsCommand::SshPasswordPrompt); if (logResponse.result != CvsResponse::Ok) { *errorMessage = logResponse.message; return false; @@ -1535,7 +1535,7 @@ bool CvsPluginPrivate::managesFile(const FilePath &workingDirectory, const QStri QStringList args; args << QLatin1String("status") << fileName; const CvsResponse response = - runCvs(workingDirectory, args, m_settings.timeout.value(), ShellCommand::SshPasswordPrompt); + runCvs(workingDirectory, args, m_settings.timeout.value(), VcsCommand::SshPasswordPrompt); if (response.result != CvsResponse::Ok) return false; return !response.stdOut.contains(QLatin1String("Status: Unknown")); diff --git a/src/plugins/git/branchmodel.cpp b/src/plugins/git/branchmodel.cpp index 0cdb6fe7272..c5b2ceda476 100644 --- a/src/plugins/git/branchmodel.cpp +++ b/src/plugins/git/branchmodel.cpp @@ -27,11 +27,11 @@ #include "gitclient.h" #include "gitconstants.h" +#include #include #include #include -#include #include #include @@ -624,7 +624,7 @@ void BranchModel::removeTag(const QModelIndex &idx) removeNode(idx); } -ShellCommand *BranchModel::checkoutBranch(const QModelIndex &idx) +VcsCommand *BranchModel::checkoutBranch(const QModelIndex &idx) { QString branch = fullName(idx, !isLocal(idx)); if (branch.isEmpty()) @@ -690,7 +690,7 @@ QModelIndex BranchModel::addBranch(const QString &name, bool track, const QModel } else { const QStringList arguments({"-n1", "--format=%H %ct"}); if (d->client->synchronousLog(d->workingDirectory, arguments, &output, &errorMessage, - ShellCommand::SuppressCommandLogging)) { + VcsCommand::SuppressCommandLogging)) { const QStringList values = output.split(' '); startSha = values[0]; branchDateTime = QDateTime::fromSecsSinceEpoch(values[1].toLongLong()); @@ -908,9 +908,9 @@ void BranchModel::updateUpstreamStatus(BranchNode *node) { if (node->tracking.isEmpty()) return; - ShellCommand *command = d->client->asyncUpstreamStatus( + VcsCommand *command = d->client->asyncUpstreamStatus( d->workingDirectory, node->fullRef(), node->tracking); - QObject::connect(command, &ShellCommand::stdOutText, node, [this, node](const QString &text) { + QObject::connect(command, &VcsCommand::stdOutText, node, [this, node](const QString &text) { if (text.isEmpty()) return; const QStringList split = text.trimmed().split('\t'); @@ -930,7 +930,7 @@ QString BranchModel::toolTip(const QString &sha) const QStringList arguments("-n1"); arguments << sha; if (!d->client->synchronousLog(d->workingDirectory, arguments, &output, &errorMessage, - ShellCommand::SuppressCommandLogging)) { + VcsCommand::SuppressCommandLogging)) { return errorMessage; } return output; diff --git a/src/plugins/git/branchmodel.h b/src/plugins/git/branchmodel.h index 2ed3fc908bf..267e911e914 100644 --- a/src/plugins/git/branchmodel.h +++ b/src/plugins/git/branchmodel.h @@ -31,7 +31,7 @@ #include #include -namespace Utils { class ShellCommand; } +namespace VcsBase { class VcsCommand; } namespace Git { namespace Internal { @@ -80,7 +80,7 @@ public: void removeBranch(const QModelIndex &idx); void removeTag(const QModelIndex &idx); - Utils::ShellCommand *checkoutBranch(const QModelIndex &idx); + VcsBase::VcsCommand *checkoutBranch(const QModelIndex &idx); bool branchIsMerged(const QModelIndex &idx); QModelIndex addBranch(const QString &name, bool track, const QModelIndex &trackedBranch); void setRemoteTracking(const QModelIndex &trackingIndex); diff --git a/src/plugins/git/branchview.cpp b/src/plugins/git/branchview.cpp index 9d37011567a..4dbb289298c 100644 --- a/src/plugins/git/branchview.cpp +++ b/src/plugins/git/branchview.cpp @@ -36,12 +36,14 @@ #include #include #include + #include #include #include #include -#include #include + +#include #include #include @@ -57,6 +59,7 @@ using namespace Core; using namespace Utils; +using namespace VcsBase; namespace Git { namespace Internal { @@ -435,11 +438,11 @@ bool BranchView::checkout() return false; } - ShellCommand *command = m_model->checkoutBranch(selected); + VcsCommand *command = m_model->checkoutBranch(selected); const bool moveChanges = branchCheckoutDialog.moveLocalChangesToNextBranch(); const bool popStash = branchCheckoutDialog.popStashOfNextBranch(); if (command && (moveChanges || popStash)) { - connect(command, &ShellCommand::finished, + connect(command, &VcsCommand::finished, this, [this, client, popMessageStart, moveChanges, popStash] { if (moveChanges) { client->endStashScope(m_repository); diff --git a/src/plugins/git/changeselectiondialog.cpp b/src/plugins/git/changeselectiondialog.cpp index 525d41d1fcf..91fbe6af3ac 100644 --- a/src/plugins/git/changeselectiondialog.cpp +++ b/src/plugins/git/changeselectiondialog.cpp @@ -32,9 +32,10 @@ #include #include -#include #include +#include + #include #include #include @@ -48,6 +49,7 @@ #include using namespace Utils; +using namespace VcsBase; namespace Git { namespace Internal { @@ -194,9 +196,9 @@ void ChangeSelectionDialog::recalculateCompletion() return; GitClient *client = GitClient::instance(); - ShellCommand *command = client->asyncForEachRefCmd(workingDir, {"--format=%(refname:short)"}); - connect(this, &QObject::destroyed, command, &ShellCommand::abort); - connect(command, &ShellCommand::stdOutText, [this](const QString &output) { + VcsCommand *command = client->asyncForEachRefCmd(workingDir, {"--format=%(refname:short)"}); + connect(this, &QObject::destroyed, command, &VcsCommand::abort); + connect(command, &VcsCommand::stdOutText, [this](const QString &output) { m_changeModel->setStringList(output.split('\n')); }); } diff --git a/src/plugins/git/gerrit/gerritserver.cpp b/src/plugins/git/gerrit/gerritserver.cpp index 78a67471f9f..36f07a369d7 100644 --- a/src/plugins/git/gerrit/gerritserver.cpp +++ b/src/plugins/git/gerrit/gerritserver.cpp @@ -32,7 +32,8 @@ #include #include -#include + +#include #include #include @@ -41,8 +42,9 @@ #include #include -using namespace Utils; using namespace Git::Internal; +using namespace Utils; +using namespace VcsBase; namespace Gerrit { namespace Internal { @@ -243,7 +245,7 @@ int GerritServer::testConnection() static GitClient *const client = GitClient::instance(); const QStringList arguments = curlArguments() << (url(RestUrl) + accountUrlC); const CommandResult result = client->vcsFullySynchronousExec({}, {curlBinary, arguments}, - ShellCommand::NoOutput); + VcsCommand::NoOutput); if (result.result() == ProcessResult::FinishedWithSuccess) { QString output = result.cleanedStdOut(); // Gerrit returns an empty response for /p/qt-creator/a/accounts/self @@ -343,7 +345,7 @@ bool GerritServer::resolveVersion(const GerritParameters &p, bool forceReload) arguments << p.portFlag << QString::number(port); arguments << hostArgument() << "gerrit" << "version"; const CommandResult result = client->vcsFullySynchronousExec({}, {p.ssh, arguments}, - ShellCommand::NoOutput); + VcsCommand::NoOutput); QString stdOut = result.cleanedStdOut().trimmed(); stdOut.remove("gerrit version "); version = stdOut; @@ -352,7 +354,7 @@ bool GerritServer::resolveVersion(const GerritParameters &p, bool forceReload) } else { const QStringList arguments = curlArguments() << (url(RestUrl) + versionUrlC); const CommandResult result = client->vcsFullySynchronousExec({}, {curlBinary, arguments}, - ShellCommand::NoOutput); + VcsCommand::NoOutput); // REST endpoint for version is only available from 2.8 and up. Do not consider invalid // if it fails. if (result.result() == ProcessResult::FinishedWithSuccess) { diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp index 6f8d31d6fec..6fc070bc92a 100644 --- a/src/plugins/git/gitclient.cpp +++ b/src/plugins/git/gitclient.cpp @@ -49,7 +49,6 @@ #include #include #include -#include #include #include #include @@ -60,6 +59,7 @@ #include #include #include +#include #include #include @@ -116,12 +116,12 @@ static GitClient *m_instance = nullptr; // Suppress git diff warnings about "LF will be replaced by CRLF..." on Windows. static unsigned diffExecutionFlags() { - return HostOsInfo::isWindowsHost() ? unsigned(ShellCommand::SuppressStdErr) : 0u; + return HostOsInfo::isWindowsHost() ? unsigned(VcsCommand::SuppressStdErr) : 0u; } -const unsigned silentFlags = unsigned(ShellCommand::SuppressCommandLogging - | ShellCommand::SuppressStdErr - | ShellCommand::SuppressFailMessage); +const unsigned silentFlags = unsigned(VcsCommand::SuppressCommandLogging + | VcsCommand::SuppressStdErr + | VcsCommand::SuppressFailMessage); static QString branchesDisplay(const QString &prefix, QStringList *branches, bool *first) { @@ -345,11 +345,11 @@ void GitBaseDiffEditorController::updateBranchList() return; const FilePath workingDirectory = baseDirectory(); - ShellCommand *command = m_instance->vcsExec( + VcsCommand *command = m_instance->vcsExec( workingDirectory, {"branch", noColorOption, "-a", "--contains", revision}, nullptr, false, 0, workingDirectory.toString()); - connect(command, &ShellCommand::stdOutText, this, [this](const QString &text) { + connect(command, &VcsCommand::stdOutText, this, [this](const QString &text) { const QString remotePrefix = "remotes/"; const QString localPrefix = ""; const int prefixLength = remotePrefix.length(); @@ -484,7 +484,7 @@ private: QString m_body; QString m_precedes; std::vector m_follows; - QList> m_commands; + QList> m_commands; }; void ShowController::processCommandOutput(const QString &output) @@ -562,7 +562,7 @@ void ShowController::updateDescription() void ShowController::abortCommands() { - for (QPointer command : m_commands) { + for (QPointer command : m_commands) { if (command) command->abort(); } @@ -743,16 +743,16 @@ class ConflictHandler final : public QObject { Q_OBJECT public: - static void attachToCommand(ShellCommand *command, const QString &abortCommand = QString()) { + static void attachToCommand(VcsCommand *command, const QString &abortCommand = QString()) { auto handler = new ConflictHandler(command->defaultWorkingDirectory(), abortCommand); handler->setParent(command); // delete when command goes out of scope - command->addFlags(ShellCommand::ExpectRepoChanges); - connect(command, &ShellCommand::stdOutText, handler, &ConflictHandler::readStdOut); - connect(command, &ShellCommand::stdErrText, handler, &ConflictHandler::readStdErr); + command->addFlags(VcsCommand::ExpectRepoChanges); + connect(command, &VcsCommand::stdOutText, handler, &ConflictHandler::readStdOut); + connect(command, &VcsCommand::stdErrText, handler, &ConflictHandler::readStdErr); } - static void handleResponse(const Utils::CommandResult &result, + static void handleResponse(const VcsBase::CommandResult &result, const FilePath &workingDirectory, const QString &abortCommand = QString()) { @@ -811,7 +811,7 @@ private: class GitProgressParser : public ProgressParser { public: - static void attachToCommand(ShellCommand *command) + static void attachToCommand(VcsCommand *command) { command->setProgressParser(new GitProgressParser); } @@ -922,7 +922,7 @@ QString GitClient::findGitDirForRepository(const FilePath &repositoryDir) const bool GitClient::managesFile(const FilePath &workingDirectory, const QString &fileName) const { const CommandResult result = vcsFullySynchronousExec(workingDirectory, - {"ls-files", "--error-unmatch", fileName}, ShellCommand::NoOutput); + {"ls-files", "--error-unmatch", fileName}, VcsCommand::NoOutput); return result.result() == ProcessResult::FinishedWithSuccess; } @@ -937,7 +937,7 @@ FilePaths GitClient::unmanagedFiles(const FilePaths &filePaths) const QStringList args({"ls-files", "-z"}); const QDir wd(it.key().toString()); args << transform(it.value(), [&wd](const QString &fp) { return wd.relativeFilePath(fp); }); - const CommandResult result = vcsFullySynchronousExec(it.key(), args, ShellCommand::NoOutput); + const CommandResult result = vcsFullySynchronousExec(it.key(), args, VcsCommand::NoOutput); if (result.result() != ProcessResult::FinishedWithSuccess) return filePaths; const QStringList managedFilePaths @@ -1147,8 +1147,8 @@ void GitClient::merge(const FilePath &workingDirectory, const QStringList &unmer void GitClient::status(const FilePath &workingDirectory) const { VcsOutputWindow::setRepository(workingDirectory.toString()); - ShellCommand *command = vcsExec(workingDirectory, {"status", "-u"}, nullptr, true); - connect(command, &ShellCommand::finished, VcsOutputWindow::instance(), + VcsCommand *command = vcsExec(workingDirectory, {"status", "-u"}, nullptr, true); + connect(command, &VcsCommand::finished, VcsOutputWindow::instance(), &VcsOutputWindow::clearRepository, Qt::QueuedConnection); } @@ -1383,16 +1383,16 @@ VcsBaseEditorWidget *GitClient::annotate( return editor; } -ShellCommand *GitClient::checkout(const FilePath &workingDirectory, const QString &ref, +VcsCommand *GitClient::checkout(const FilePath &workingDirectory, const QString &ref, StashMode stashMode) { if (stashMode == StashMode::TryStash && !beginStashScope(workingDirectory, "Checkout")) return nullptr; QStringList arguments = setupCheckoutArguments(workingDirectory, ref); - ShellCommand *command = vcsExec( + VcsCommand *command = vcsExec( workingDirectory, arguments, nullptr, true, - ShellCommand::ExpectRepoChanges | ShellCommand::ShowSuccessMessage); - connect(command, &ShellCommand::finished, + VcsCommand::ExpectRepoChanges | VcsCommand::ShowSuccessMessage); + connect(command, &VcsCommand::finished, this, [this, workingDirectory, stashMode](bool success) { if (stashMode == StashMode::TryStash) endStashScope(workingDirectory); @@ -1481,7 +1481,7 @@ void GitClient::reset(const FilePath &workingDirectory, const QString &argument, if (!commit.isEmpty()) arguments << commit; - unsigned flags = ShellCommand::ShowSuccessMessage; + unsigned flags = VcsCommand::ShowSuccessMessage; if (argument == "--hard") { if (gitStatus(workingDirectory, StatusMode(NoUntracked | NoSubmodules)) != StatusUnchanged) { if (QMessageBox::question( @@ -1492,7 +1492,7 @@ void GitClient::reset(const FilePath &workingDirectory, const QString &argument, return; } } - flags |= ShellCommand::ExpectRepoChanges; + flags |= VcsCommand::ExpectRepoChanges; } vcsExec(workingDirectory, arguments, nullptr, true, flags); } @@ -1501,10 +1501,10 @@ void GitClient::removeStaleRemoteBranches(const FilePath &workingDirectory, cons { const QStringList arguments = {"remote", "prune", remote}; - ShellCommand *command = vcsExec(workingDirectory, arguments, nullptr, true, - ShellCommand::ShowSuccessMessage); + VcsCommand *command = vcsExec(workingDirectory, arguments, nullptr, true, + VcsCommand::ShowSuccessMessage); - connect(command, &ShellCommand::finished, this, [workingDirectory](bool success) { + connect(command, &VcsCommand::finished, this, [workingDirectory](bool success) { if (success) GitPlugin::updateBranches(workingDirectory); }); @@ -1513,7 +1513,7 @@ void GitClient::removeStaleRemoteBranches(const FilePath &workingDirectory, cons void GitClient::recoverDeletedFiles(const FilePath &workingDirectory) { const CommandResult result = vcsFullySynchronousExec(workingDirectory, {"ls-files", "--deleted"}, - ShellCommand::SuppressCommandLogging); + VcsCommand::SuppressCommandLogging); if (result.result() == ProcessResult::FinishedWithSuccess) { const QString stdOut = result.cleanedStdOut().trimmed(); if (stdOut.isEmpty()) { @@ -1639,7 +1639,7 @@ bool GitClient::synchronousCheckoutFiles(const FilePath &workingDirectory, QStri arguments << revision; arguments << "--" << files; const CommandResult result = vcsFullySynchronousExec(workingDirectory, arguments, - ShellCommand::ExpectRepoChanges); + VcsCommand::ExpectRepoChanges); if (result.result() == ProcessResult::FinishedWithSuccess) return true; @@ -1827,7 +1827,7 @@ QString GitClient::synchronousTopic(const FilePath &workingDirectory) const // No tag or remote branch - try git describe const CommandResult result = vcsFullySynchronousExec(workingDirectory, QStringList{"describe"}, - ShellCommand::NoOutput); + VcsCommand::NoOutput); if (result.result() == ProcessResult::FinishedWithSuccess) { const QString stdOut = result.cleanedStdOut().trimmed(); if (!stdOut.isEmpty()) @@ -1961,9 +1961,9 @@ bool GitClient::executeSynchronousStash(const FilePath &workingDirectory, arguments << "--keep-index"; if (!message.isEmpty()) arguments << message; - const unsigned flags = ShellCommand::ShowStdOut - | ShellCommand::ExpectRepoChanges - | ShellCommand::ShowSuccessMessage; + const unsigned flags = VcsCommand::ShowStdOut + | VcsCommand::ExpectRepoChanges + | VcsCommand::ShowSuccessMessage; const CommandResult result = vcsSynchronousExec(workingDirectory, arguments, flags); if (result.result() == ProcessResult::FinishedWithSuccess) return true; @@ -2033,7 +2033,7 @@ bool GitClient::synchronousForEachRefCmd(const FilePath &workingDirectory, QStri return false; } -ShellCommand *GitClient::asyncForEachRefCmd(const FilePath &workingDirectory, QStringList args) const +VcsCommand *GitClient::asyncForEachRefCmd(const FilePath &workingDirectory, QStringList args) const { args.push_front("for-each-ref"); return vcsExec(workingDirectory, args, nullptr, false, silentFlags); @@ -2182,7 +2182,7 @@ bool GitClient::cleanList(const FilePath &workingDirectory, const QString &modul const QStringList arguments = {"clean", "--dry-run", flag}; const CommandResult result = vcsFullySynchronousExec(directory, arguments, - ShellCommand::ForceCLocale); + VcsCommand::ForceCLocale); if (result.result() != ProcessResult::FinishedWithSuccess) { msgCannotRun(arguments, directory, result.cleanedStdErr(), errorMessage); return false; @@ -2339,9 +2339,9 @@ void GitClient::updateSubmodulesIfNeeded(const FilePath &workingDirectory, bool } } - ShellCommand *cmd = vcsExec(workingDirectory, {"submodule", "update"}, nullptr, true, - ShellCommand::ExpectRepoChanges); - connect(cmd, &ShellCommand::finished, this, &GitClient::finishSubmoduleUpdate); + VcsCommand *cmd = vcsExec(workingDirectory, {"submodule", "update"}, nullptr, true, + VcsCommand::ExpectRepoChanges); + connect(cmd, &VcsCommand::finished, this, &GitClient::finishSubmoduleUpdate); } void GitClient::finishSubmoduleUpdate() @@ -2506,9 +2506,9 @@ void GitClient::continuePreviousGitCommand(const FilePath &workingDirectory, QStringList GitClient::synchronousRepositoryBranches(const QString &repositoryURL, const FilePath &workingDirectory) const { - const unsigned flags = ShellCommand::SshPasswordPrompt - | ShellCommand::SuppressStdErr - | ShellCommand::SuppressFailMessage; + const unsigned flags = VcsCommand::SshPasswordPrompt + | VcsCommand::SuppressStdErr + | VcsCommand::SuppressFailMessage; const CommandResult result = vcsSynchronousExec(workingDirectory, {"ls-remote", repositoryURL, HEAD, "refs/heads/*"}, flags); QStringList branches; @@ -2783,7 +2783,7 @@ bool GitClient::getCommitData(const FilePath &workingDirectory, QString output; if (commitData.commitType == FixupCommit) { synchronousLog(repoDirectory, {HEAD, "--not", "--remotes", "-n1"}, &output, errorMessage, - ShellCommand::SuppressCommandLogging); + VcsCommand::SuppressCommandLogging); if (output.isEmpty()) { *errorMessage = msgNoCommits(false); return false; @@ -2992,7 +2992,7 @@ bool GitClient::addAndCommit(const FilePath &repositoryDirectory, } const CommandResult result = vcsSynchronousExec(repositoryDirectory, arguments, - ShellCommand::NoFullySync); + VcsCommand::NoFullySync); if (result.result() == ProcessResult::FinishedWithSuccess) { VcsOutputWindow::appendMessage(msgCommitted(amendSHA1, commitCount)); GitPlugin::updateCurrentBranch(); @@ -3115,9 +3115,9 @@ void GitClient::revertFiles(const QStringList &files, bool revertStaging) void GitClient::fetch(const FilePath &workingDirectory, const QString &remote) { QStringList const arguments = {"fetch", (remote.isEmpty() ? "--all" : remote)}; - ShellCommand *command = vcsExec(workingDirectory, arguments, nullptr, true, - ShellCommand::ShowSuccessMessage); - connect(command, &ShellCommand::finished, this, [workingDirectory](bool success) { + VcsCommand *command = vcsExec(workingDirectory, arguments, nullptr, true, + VcsCommand::ShowSuccessMessage); + connect(command, &VcsCommand::finished, this, [workingDirectory](bool success) { if (success) GitPlugin::updateBranches(workingDirectory); }); @@ -3128,10 +3128,10 @@ bool GitClient::executeAndHandleConflicts(const FilePath &workingDirectory, const QString &abortCommand) const { // Disable UNIX terminals to suppress SSH prompting. - const unsigned flags = ShellCommand::SshPasswordPrompt - | ShellCommand::ShowStdOut - | ShellCommand::ExpectRepoChanges - | ShellCommand::ShowSuccessMessage; + const unsigned flags = VcsCommand::SshPasswordPrompt + | VcsCommand::ShowStdOut + | VcsCommand::ExpectRepoChanges + | VcsCommand::ShowSuccessMessage; const CommandResult result = vcsSynchronousExec(workingDirectory, arguments, flags); // Notify about changed files or abort the rebase. ConflictHandler::handleResponse(result, workingDirectory, abortCommand); @@ -3149,8 +3149,8 @@ void GitClient::pull(const FilePath &workingDirectory, bool rebase) abortCommand = "merge"; } - ShellCommand *command = vcsExecAbortable(workingDirectory, arguments, rebase, abortCommand); - connect(command, &ShellCommand::finished, this, [this, workingDirectory](bool success) { + VcsCommand *command = vcsExecAbortable(workingDirectory, arguments, rebase, abortCommand); + connect(command, &VcsCommand::finished, this, [this, workingDirectory](bool success) { if (success) updateSubmodulesIfNeeded(workingDirectory, true); }, Qt::QueuedConnection); @@ -3167,7 +3167,7 @@ void GitClient::synchronousAbortCommand(const FilePath &workingDir, const QStrin } const CommandResult result = vcsFullySynchronousExec(workingDir, {abortCommand, "--abort"}, - ShellCommand::ExpectRepoChanges | ShellCommand::ShowSuccessMessage); + VcsCommand::ExpectRepoChanges | VcsCommand::ShowSuccessMessage); VcsOutputWindow::append(result.cleanedStdOut()); } @@ -3196,9 +3196,9 @@ bool GitClient::synchronousSetTrackingBranch(const FilePath &workingDirectory, return result.result() == ProcessResult::FinishedWithSuccess; } -ShellCommand *GitClient::asyncUpstreamStatus(const FilePath &workingDirectory, - const QString &branch, - const QString &upstream) +VcsCommand *GitClient::asyncUpstreamStatus(const FilePath &workingDirectory, + const QString &branch, + const QString &upstream) { const QStringList args {"rev-list", noColorOption, "--left-right", "--count", branch + "..." + upstream}; @@ -3261,9 +3261,9 @@ void GitClient::addFuture(const QFuture &future) void GitClient::synchronousSubversionFetch(const FilePath &workingDirectory) const { // Disable UNIX terminals to suppress SSH prompting. - const unsigned flags = ShellCommand::SshPasswordPrompt - | ShellCommand::ShowStdOut - | ShellCommand::ShowSuccessMessage; + const unsigned flags = VcsCommand::SshPasswordPrompt + | VcsCommand::ShowStdOut + | VcsCommand::ShowSuccessMessage; vcsSynchronousExec(workingDirectory, {"svn", "fetch"}, flags); } @@ -3286,15 +3286,14 @@ void GitClient::subversionLog(const FilePath &workingDirectory) const void GitClient::subversionDeltaCommit(const FilePath &workingDirectory) const { - vcsExec(workingDirectory, {"svn", "dcommit"}, nullptr, true, ShellCommand::ShowSuccessMessage); + vcsExec(workingDirectory, {"svn", "dcommit"}, nullptr, true, VcsCommand::ShowSuccessMessage); } void GitClient::push(const FilePath &workingDirectory, const QStringList &pushArgs) { - ShellCommand *command = vcsExec( - workingDirectory, QStringList({"push"}) + pushArgs, nullptr, true, - ShellCommand::ShowSuccessMessage); - connect(command, &ShellCommand::stdErrText, this, [this, command](const QString &text) { + VcsCommand *command = vcsExec(workingDirectory, QStringList({"push"}) + pushArgs, nullptr, true, + VcsCommand::ShowSuccessMessage); + connect(command, &VcsCommand::stdErrText, this, [this, command](const QString &text) { if (text.contains("non-fast-forward")) command->setCookie(NonFastForward); else if (text.contains("has no upstream branch")) @@ -3316,7 +3315,7 @@ void GitClient::push(const FilePath &workingDirectory, const QStringList &pushAr } } }); - connect(command, &ShellCommand::finished, + connect(command, &VcsCommand::finished, this, [this, command, workingDirectory, pushArgs](bool success) { if (!success) { switch (static_cast(command->cookie().toInt())) { @@ -3331,10 +3330,10 @@ void GitClient::push(const FilePath &workingDirectory, const QStringList &pushAr .arg(QString::number(warnColor.rgba(), 16)), QMessageBox::Yes | QMessageBox::No, QMessageBox::No) == QMessageBox::Yes) { - ShellCommand *rePushCommand = vcsExec(workingDirectory, + VcsCommand *rePushCommand = vcsExec(workingDirectory, QStringList({"push", "--force-with-lease"}) + pushArgs, - nullptr, true, ShellCommand::ShowSuccessMessage); - connect(rePushCommand, &ShellCommand::finished, this, [](bool success) { + nullptr, true, VcsCommand::ShowSuccessMessage); + connect(rePushCommand, &VcsCommand::finished, this, [](bool success) { if (success) GitPlugin::updateCurrentBranch(); }); @@ -3354,10 +3353,10 @@ void GitClient::push(const FilePath &workingDirectory, const QStringList &pushAr const QStringList fallbackCommandParts = m_pushFallbackCommand.split(' ', Qt::SkipEmptyParts); - ShellCommand *rePushCommand = vcsExec(workingDirectory, + VcsCommand *rePushCommand = vcsExec(workingDirectory, fallbackCommandParts.mid(1), nullptr, true, - ShellCommand::ShowSuccessMessage); - connect(rePushCommand, &ShellCommand::finished, this, + VcsCommand::ShowSuccessMessage); + connect(rePushCommand, &VcsCommand::finished, this, [workingDirectory](bool success) { if (success) GitPlugin::updateBranches(workingDirectory); @@ -3412,20 +3411,20 @@ void GitClient::revert(const FilePath &workingDirectory, const QString &argument // Executes a command asynchronously. Work tree is expected to be clean. // Stashing is handled prior to this call. -ShellCommand *GitClient::vcsExecAbortable(const FilePath &workingDirectory, - const QStringList &arguments, - bool isRebase, - QString abortCommand) +VcsCommand *GitClient::vcsExecAbortable(const FilePath &workingDirectory, + const QStringList &arguments, + bool isRebase, + QString abortCommand) { QTC_ASSERT(!arguments.isEmpty(), return nullptr); if (abortCommand.isEmpty()) abortCommand = arguments.at(0); - ShellCommand *command = createCommand(workingDirectory, nullptr, VcsWindowOutputBind); + VcsCommand *command = createCommand(workingDirectory, nullptr, VcsWindowOutputBind); command->setCookie(workingDirectory.toString()); - command->addFlags(ShellCommand::SshPasswordPrompt - | ShellCommand::ShowStdOut - | ShellCommand::ShowSuccessMessage); + command->addFlags(VcsCommand::SshPasswordPrompt + | VcsCommand::ShowStdOut + | VcsCommand::ShowSuccessMessage); // For rebase, Git might request an editor (which means the process keeps running until the // user closes it), so run without timeout. command->addJob({vcsBinary(), arguments}, isRebase ? 0 : command->defaultTimeoutS()); @@ -3490,8 +3489,8 @@ void GitClient::stashPop(const FilePath &workingDirectory, const QString &stash) QStringList arguments = {"stash", "pop"}; if (!stash.isEmpty()) arguments << stash; - ShellCommand *cmd = vcsExec(workingDirectory, arguments, nullptr, true, - ShellCommand::ExpectRepoChanges); + VcsCommand *cmd = vcsExec(workingDirectory, arguments, nullptr, true, + VcsCommand::ExpectRepoChanges); ConflictHandler::attachToCommand(cmd); } @@ -3535,7 +3534,7 @@ bool GitClient::synchronousStashList(const FilePath &workingDirectory, QListsynchronousLog(workingDirectory, {"-n", "1", "--format=%s", target}, - &subject, nullptr, ShellCommand::NoOutput); + &subject, nullptr, VcsCommand::NoOutput); initialName = subject.trimmed(); } QString suggestedName = initialName; diff --git a/src/plugins/git/gitclient.h b/src/plugins/git/gitclient.h index 5031b3f6e62..5b793711899 100644 --- a/src/plugins/git/gitclient.h +++ b/src/plugins/git/gitclient.h @@ -53,11 +53,10 @@ class ChunkSelection; class DiffEditorController; } -namespace Utils { class ShellCommand; } - namespace VcsBase { class SubmitFileModel; class VcsBaseEditorWidget; +class VcsCommand; } namespace Git { @@ -148,7 +147,7 @@ public: Utils::FilePath vcsBinary() const override; QFuture gitVersion() const; - Utils::ShellCommand *vcsExecAbortable(const Utils::FilePath &workingDirectory, + VcsBase::VcsCommand *vcsExecAbortable(const Utils::FilePath &workingDirectory, const QStringList &arguments, bool isRebase = false, QString abortCommand = {}); @@ -208,7 +207,7 @@ public: QString revision = {}, QString *errorMessage = nullptr, bool revertStaging = true); enum class StashMode { NoStash, TryStash }; - Utils::ShellCommand *checkout(const Utils::FilePath &workingDirectory, const QString &ref, + VcsBase::VcsCommand *checkout(const Utils::FilePath &workingDirectory, const QString &ref, StashMode stashMode = StashMode::TryStash); QStringList setupCheckoutArguments(const Utils::FilePath &workingDirectory, const QString &ref); @@ -237,7 +236,7 @@ public: QString *output, QString *errorMessage) const; bool synchronousForEachRefCmd(const Utils::FilePath &workingDirectory, QStringList args, QString *output, QString *errorMessage = nullptr) const; - Utils::ShellCommand *asyncForEachRefCmd(const Utils::FilePath &workingDirectory, QStringList args) const; + VcsBase::VcsCommand *asyncForEachRefCmd(const Utils::FilePath &workingDirectory, QStringList args) const; bool synchronousRemoteCmd(const Utils::FilePath &workingDirectory, QStringList remoteArgs, QString *output = nullptr, QString *errorMessage = nullptr, bool silent = false) const; @@ -360,7 +359,7 @@ public: void show(const QString &source, const QString &id, const QString &name = {}); void archive(const Utils::FilePath &workingDirectory, QString commit); - Utils::ShellCommand *asyncUpstreamStatus(const Utils::FilePath &workingDirectory, + VcsBase::VcsCommand *asyncUpstreamStatus(const Utils::FilePath &workingDirectory, const QString &branch, const QString &upstream); enum class BranchTargetType { Remote, Commit }; @@ -396,7 +395,7 @@ private: bool *isDirectory, QString *errorMessage, bool revertStaging); - void connectRepositoryChanged(const QString & repository, Utils::ShellCommand *cmd); + void connectRepositoryChanged(const QString & repository, VcsBase::VcsCommand *cmd); bool executeAndHandleConflicts(const Utils::FilePath &workingDirectory, const QStringList &arguments, const QString &abortCommand = {}) const; void tryLaunchingGitK(const Utils::Environment &env, diff --git a/src/plugins/git/gitgrep.cpp b/src/plugins/git/gitgrep.cpp index 7bf8c8dfebf..541fd4e132c 100644 --- a/src/plugins/git/gitgrep.cpp +++ b/src/plugins/git/gitgrep.cpp @@ -29,8 +29,11 @@ #include #include #include + #include + #include +#include #include #include @@ -39,7 +42,6 @@ #include #include #include -#include #include #include @@ -64,6 +66,7 @@ public: using namespace Core; using namespace Utils; +using namespace VcsBase; namespace { @@ -187,16 +190,16 @@ public: return QString(":!" + filter); }); arguments << "--" << filterArgs << exclusionArgs; - m_command->addFlags(ShellCommand::SilentOutput | ShellCommand::SuppressFailMessage); + m_command->addFlags(VcsCommand::SilentOutput | VcsCommand::SuppressFailMessage); m_command->setProgressiveOutput(true); QFutureWatcher watcher; QObject::connect(&watcher, &QFutureWatcher::canceled, m_command.get(), - &ShellCommand::cancel); + &VcsCommand::cancel); watcher.setFuture(fi.future()); QObject::connect(m_command.get(), - &ShellCommand::stdOutText, + &VcsCommand::stdOutText, [this, &fi](const QString &text) { read(fi, text); }); const CommandResult result = m_command->runCommand({m_vcsBinary, arguments}, {}, 0); switch (result.result()) { @@ -218,7 +221,7 @@ private: FilePath m_directory; QString m_ref; TextEditor::FileFindParameters m_parameters; - std::unique_ptr m_command; + std::unique_ptr m_command; }; } // namespace diff --git a/src/plugins/git/gitplugin.cpp b/src/plugins/git/gitplugin.cpp index 2fe82c984bc..0f0cce545cc 100644 --- a/src/plugins/git/gitplugin.cpp +++ b/src/plugins/git/gitplugin.cpp @@ -66,18 +66,18 @@ #include #include #include -#include #include #include #include -#include -#include -#include #include -#include #include +#include +#include +#include #include +#include +#include #include #include @@ -255,10 +255,10 @@ public: void vcsDescribe(const FilePath &source, const QString &id) final { m_gitClient.show(source.toString(), id); }; QString vcsTopic(const FilePath &directory) final; - ShellCommand *createInitialCheckoutCommand(const QString &url, - const Utils::FilePath &baseDirectory, - const QString &localName, - const QStringList &extraArgs) final; + VcsCommand *createInitialCheckoutCommand(const QString &url, + const Utils::FilePath &baseDirectory, + const QString &localName, + const QStringList &extraArgs) final; void fillLinkContextMenu(QMenu *menu, const FilePath &workingDirectory, @@ -1880,16 +1880,16 @@ QString GitPluginPrivate::vcsTopic(const FilePath &directory) return topic; } -ShellCommand *GitPluginPrivate::createInitialCheckoutCommand(const QString &url, - const Utils::FilePath &baseDirectory, - const QString &localName, - const QStringList &extraArgs) +VcsCommand *GitPluginPrivate::createInitialCheckoutCommand(const QString &url, + const Utils::FilePath &baseDirectory, + const QString &localName, + const QStringList &extraArgs) { QStringList args = {"clone", "--progress"}; args << extraArgs << url << localName; auto command = VcsBaseClient::createVcsCommand(baseDirectory, m_gitClient.processEnvironment()); - command->addFlags(ShellCommand::SuppressStdErr); + command->addFlags(VcsCommand::SuppressStdErr); command->addJob({m_gitClient.vcsBinary(), args}, -1); return command; } diff --git a/src/plugins/git/logchangedialog.cpp b/src/plugins/git/logchangedialog.cpp index e53ccfa24fc..877e4c16569 100644 --- a/src/plugins/git/logchangedialog.cpp +++ b/src/plugins/git/logchangedialog.cpp @@ -26,10 +26,10 @@ #include "logchangedialog.h" #include "gitclient.h" +#include #include #include -#include #include #include @@ -67,9 +67,8 @@ public: const auto it = m_descriptions.constFind(revision); if (it != m_descriptions.constEnd()) return *it; - const QString desc = QString::fromUtf8( - GitClient::instance()->synchronousShow( - m_workingDirectory, revision, ShellCommand::NoOutput)); + const QString desc = QString::fromUtf8(GitClient::instance()->synchronousShow( + m_workingDirectory, revision, VcsCommand::NoOutput)); m_descriptions[revision] = desc; return desc; } @@ -192,7 +191,7 @@ bool LogChangeWidget::populateLog(const FilePath &repository, const QString &com arguments << "--"; QString output; if (!GitClient::instance()->synchronousLog( - repository, arguments, &output, nullptr, ShellCommand::NoOutput)) { + repository, arguments, &output, nullptr, VcsCommand::NoOutput)) { return false; } const QStringList lines = output.split('\n'); diff --git a/src/plugins/gitlab/gitlabclonedialog.cpp b/src/plugins/gitlab/gitlabclonedialog.cpp index 101c7ce5782..b295ab83729 100644 --- a/src/plugins/gitlab/gitlabclonedialog.cpp +++ b/src/plugins/gitlab/gitlabclonedialog.cpp @@ -30,9 +30,12 @@ #include #include + #include + #include #include + #include #include #include @@ -43,7 +46,8 @@ #include #include #include -#include + +#include #include #include @@ -152,13 +156,13 @@ void GitLabCloneDialog::cloneProject() m_directoryLE->text(), extraArgs); const Utils::FilePath workingDirectory = m_pathChooser->absoluteFilePath(); m_command->setProgressiveOutput(true); - connect(m_command, &Utils::ShellCommand::stdOutText, this, [this](const QString &text) { + connect(m_command, &VcsBase::VcsCommand::stdOutText, this, [this](const QString &text) { m_cloneOutput->appendPlainText(text); }); - connect(m_command, &Utils::ShellCommand::stdErrText, this, [this](const QString &text) { + connect(m_command, &VcsBase::VcsCommand::stdErrText, this, [this](const QString &text) { m_cloneOutput->appendPlainText(text); }); - connect(m_command, &Utils::ShellCommand::finished, this, &GitLabCloneDialog::cloneFinished); + connect(m_command, &VcsBase::VcsCommand::finished, this, &GitLabCloneDialog::cloneFinished); QApplication::setOverrideCursor(Qt::WaitCursor); m_cloneOutput->clear(); diff --git a/src/plugins/gitlab/gitlabclonedialog.h b/src/plugins/gitlab/gitlabclonedialog.h index 75bc20b9826..d7123f65aa9 100644 --- a/src/plugins/gitlab/gitlabclonedialog.h +++ b/src/plugins/gitlab/gitlabclonedialog.h @@ -39,9 +39,10 @@ namespace Utils { class FancyLineEdit; class InfoLabel; class PathChooser; -class ShellCommand; } +namespace VcsBase { class VcsCommand; } + namespace GitLab { class Project; @@ -66,7 +67,7 @@ private: Utils::PathChooser *m_pathChooser = nullptr; Utils::FancyLineEdit *m_directoryLE = nullptr; Utils::InfoLabel *m_infoLabel = nullptr; - Utils::ShellCommand *m_command = nullptr; + VcsBase::VcsCommand *m_command = nullptr; bool m_commandRunning = false; }; diff --git a/src/plugins/mercurial/mercurialclient.cpp b/src/plugins/mercurial/mercurialclient.cpp index 587ffb791cf..83ef9572b69 100644 --- a/src/plugins/mercurial/mercurialclient.cpp +++ b/src/plugins/mercurial/mercurialclient.cpp @@ -28,18 +28,18 @@ #include -#include -#include -#include -#include -#include - #include #include #include #include #include -#include + +#include +#include +#include +#include +#include +#include #include #include @@ -118,9 +118,9 @@ bool MercurialClient::synchronousClone(const FilePath &workingDirectory, { Q_UNUSED(srcLocation) Q_UNUSED(extraOptions) - const unsigned flags = ShellCommand::SshPasswordPrompt - | ShellCommand::ShowStdOut - | ShellCommand::ShowSuccessMessage; + const unsigned flags = VcsCommand::SshPasswordPrompt + | VcsCommand::ShowStdOut + | VcsCommand::ShowSuccessMessage; if (workingDirectory.exists()) { // Let's make first init @@ -165,15 +165,15 @@ bool MercurialClient::synchronousPull(const FilePath &workingDir, const QString QStringList args; args << vcsCommandString(PullCommand) << extraOptions << srcLocation; // Disable UNIX terminals to suppress SSH prompting - const unsigned flags = ShellCommand::SshPasswordPrompt - | ShellCommand::ShowStdOut - | ShellCommand::ShowSuccessMessage; + const unsigned flags = VcsCommand::SshPasswordPrompt + | VcsCommand::ShowStdOut + | VcsCommand::ShowSuccessMessage; // cause mercurial doesn`t understand LANG Environment env = Environment::systemEnvironment(); env.set("LANGUAGE", "C"); - ShellCommand *command = VcsBaseClient::createVcsCommand(workingDir, env); + VcsCommand *command = VcsBaseClient::createVcsCommand(workingDir, env); command->addFlags(flags); const CommandResult result = command->runCommand({vcsBinary(), args}, workingDir, vcsTimeoutS()); delete command; diff --git a/src/plugins/mercurial/mercurialplugin.cpp b/src/plugins/mercurial/mercurialplugin.cpp index 5f206f27c38..93fb41e9ebc 100644 --- a/src/plugins/mercurial/mercurialplugin.cpp +++ b/src/plugins/mercurial/mercurialplugin.cpp @@ -48,12 +48,12 @@ #include #include #include -#include #include #include #include #include +#include #include #include @@ -146,10 +146,10 @@ public: void vcsAnnotate(const FilePath &filePath, int line) final; void vcsDescribe(const FilePath &source, const QString &id) final { m_client.view(source.toString(), id); } - ShellCommand *createInitialCheckoutCommand(const QString &url, - const Utils::FilePath &baseDirectory, - const QString &localName, - const QStringList &extraArgs) final; + VcsCommand *createInitialCheckoutCommand(const QString &url, + const Utils::FilePath &baseDirectory, + const QString &localName, + const QStringList &extraArgs) final; bool sccManaged(const QString &filename); @@ -826,10 +826,10 @@ void MercurialPluginPrivate::vcsAnnotate(const FilePath &filePath, int line) m_client.annotate(filePath.parentDir(), filePath.fileName(), QString(), line); } -ShellCommand *MercurialPluginPrivate::createInitialCheckoutCommand(const QString &url, - const Utils::FilePath &baseDirectory, - const QString &localName, - const QStringList &extraArgs) +VcsCommand *MercurialPluginPrivate::createInitialCheckoutCommand(const QString &url, + const Utils::FilePath &baseDirectory, + const QString &localName, + const QStringList &extraArgs) { QStringList args; args << QLatin1String("clone") << extraArgs << url << localName; diff --git a/src/plugins/subversion/subversionclient.cpp b/src/plugins/subversion/subversionclient.cpp index 511f3ea757e..a831e8c09a1 100644 --- a/src/plugins/subversion/subversionclient.cpp +++ b/src/plugins/subversion/subversionclient.cpp @@ -29,12 +29,6 @@ #include -#include -#include -#include -#include -#include - #include #include @@ -43,7 +37,13 @@ #include #include #include -#include + +#include +#include +#include +#include +#include +#include #include #include @@ -94,7 +94,7 @@ bool SubversionClient::doCommit(const FilePath &repositoryRoot, << commitMessageFile << escapeFiles(files); const CommandResult result = vcsSynchronousExec(repositoryRoot, args, - ShellCommand::ShowStdOut | ShellCommand::NoFullySync); + VcsCommand::ShowStdOut | VcsCommand::NoFullySync); return result.result() == ProcessResult::FinishedWithSuccess; } @@ -222,7 +222,7 @@ void SubversionDiffEditorController::requestDescription() args << m_authenticationOptions; args << QLatin1String("-r"); args << QString::number(m_changeNumber); - runCommand(QList() << args, ShellCommand::SshPasswordPrompt); + runCommand(QList() << args, VcsCommand::SshPasswordPrompt); } void SubversionDiffEditorController::requestDiff() diff --git a/src/plugins/subversion/subversionplugin.cpp b/src/plugins/subversion/subversionplugin.cpp index 4d2a6492a65..8b7fa179fe2 100644 --- a/src/plugins/subversion/subversionplugin.cpp +++ b/src/plugins/subversion/subversionplugin.cpp @@ -31,15 +31,6 @@ #include "subversionsettings.h" #include "subversionsubmiteditor.h" -#include -#include -#include -#include -#include -#include - -#include - #include #include #include @@ -50,6 +41,8 @@ #include #include +#include + #include #include #include @@ -57,9 +50,16 @@ #include #include #include -#include #include +#include +#include +#include +#include +#include +#include +#include + #include #include #include @@ -108,7 +108,7 @@ const char CMD_ID_UPDATE[] = "Subversion.Update"; const char CMD_ID_COMMIT_PROJECT[] = "Subversion.CommitProject"; const char CMD_ID_DESCRIBE[] = "Subversion.Describe"; -const int s_defaultFlags = ShellCommand::SshPasswordPrompt | ShellCommand::ShowStdOut; +const int s_defaultFlags = VcsCommand::SshPasswordPrompt | VcsCommand::ShowStdOut; struct SubversionResponse { @@ -224,10 +224,10 @@ public: void vcsAnnotate(const FilePath &file, int line) final; void vcsDescribe(const FilePath &source, const QString &changeNr) final; - ShellCommand *createInitialCheckoutCommand(const QString &url, - const Utils::FilePath &baseDirectory, - const QString &localName, - const QStringList &extraArgs) final; + VcsCommand *createInitialCheckoutCommand(const QString &url, + const Utils::FilePath &baseDirectory, + const QString &localName, + const QStringList &extraArgs) final; bool isVcsDirectory(const Utils::FilePath &fileName) const; @@ -875,7 +875,7 @@ void SubversionPluginPrivate::svnStatus(const FilePath &workingDir, const QStrin if (!relativePath.isEmpty()) args.append(SubversionClient::escapeFile(relativePath)); VcsOutputWindow::setRepository(workingDir.toString()); - runSvn(workingDir, args, ShellCommand::ShowStdOut | ShellCommand::ShowSuccessMessage); + runSvn(workingDir, args, VcsCommand::ShowStdOut | VcsCommand::ShowSuccessMessage); VcsOutputWindow::clearRepository(); } @@ -929,7 +929,7 @@ void SubversionPluginPrivate::vcsAnnotateHelper(const FilePath &workingDir, cons args.append(QDir::toNativeSeparators(SubversionClient::escapeFile(file))); const auto response = runSvn(workingDir, args, - ShellCommand::SshPasswordPrompt | ShellCommand::ForceCLocale, 1, codec); + VcsCommand::SshPasswordPrompt | VcsCommand::ForceCLocale, 1, codec); if (response.error) return; @@ -1110,7 +1110,7 @@ bool SubversionPluginPrivate::vcsMove(const FilePath &workingDir, const QString args << QDir::toNativeSeparators(SubversionClient::escapeFile(from)) << QDir::toNativeSeparators(SubversionClient::escapeFile(to)); const auto response = runSvn(workingDir, args, - s_defaultFlags | ShellCommand::FullySynchronously); + s_defaultFlags | VcsCommand::FullySynchronously); return !response.error; } @@ -1136,7 +1136,7 @@ bool SubversionPluginPrivate::vcsCheckout(const FilePath &directory, const QByte args << QLatin1String(tempUrl.toEncoded()) << directory.toString(); - const auto response = runSvn(directory, args, ShellCommand::SshPasswordPrompt, 10); + const auto response = runSvn(directory, args, VcsCommand::SshPasswordPrompt, 10); return !response.error; } @@ -1264,10 +1264,10 @@ void SubversionPluginPrivate::vcsAnnotate(const FilePath &filePath, int line) vcsAnnotateHelper(filePath.parentDir(), filePath.fileName(), QString(), line); } -ShellCommand *SubversionPluginPrivate::createInitialCheckoutCommand(const QString &url, - const Utils::FilePath &baseDirectory, - const QString &localName, - const QStringList &extraArgs) +VcsCommand *SubversionPluginPrivate::createInitialCheckoutCommand(const QString &url, + const Utils::FilePath &baseDirectory, + const QString &localName, + const QStringList &extraArgs) { QStringList args; args << QLatin1String("checkout"); diff --git a/src/plugins/vcsbase/CMakeLists.txt b/src/plugins/vcsbase/CMakeLists.txt index 28eb593f1a8..1d879a127d4 100644 --- a/src/plugins/vcsbase/CMakeLists.txt +++ b/src/plugins/vcsbase/CMakeLists.txt @@ -25,6 +25,7 @@ add_qtc_plugin(VcsBase vcsbaseeditorconfig.cpp vcsbaseeditorconfig.h vcsbaseplugin.cpp vcsbaseplugin.h vcsbasesubmiteditor.cpp vcsbasesubmiteditor.h + vcscommand.cpp vcscommand.h vcsoutputformatter.cpp vcsoutputformatter.h vcsoutputwindow.cpp vcsoutputwindow.h vcsplugin.cpp vcsplugin.h diff --git a/src/plugins/vcsbase/vcsbase.qbs b/src/plugins/vcsbase/vcsbase.qbs index ce857eeba71..0fc0d8c805f 100644 --- a/src/plugins/vcsbase/vcsbase.qbs +++ b/src/plugins/vcsbase/vcsbase.qbs @@ -61,6 +61,8 @@ QtcPlugin { "vcsbaseplugin.h", "vcsbasesubmiteditor.cpp", "vcsbasesubmiteditor.h", + "vcscommand.cpp", + "vcscommand.h", "vcsoutputformatter.cpp", "vcsoutputformatter.h", "vcsoutputwindow.cpp", diff --git a/src/plugins/vcsbase/vcsbaseclient.cpp b/src/plugins/vcsbase/vcsbaseclient.cpp index 1d62785ed9c..4779a01220d 100644 --- a/src/plugins/vcsbase/vcsbaseclient.cpp +++ b/src/plugins/vcsbase/vcsbaseclient.cpp @@ -26,6 +26,7 @@ #include "vcsbaseclient.h" #include "vcsbaseclientsettings.h" #include "vcsbaseeditorconfig.h" +#include "vcscommand.h" #include "vcsplugin.h" #include @@ -39,7 +40,6 @@ #include #include #include -#include #include #include @@ -80,18 +80,18 @@ namespace VcsBase { class VcsCommandDecorator : public QObject { public: - VcsCommandDecorator(ShellCommand *command); + VcsCommandDecorator(VcsCommand *command); ~VcsCommandDecorator(); private: void addTask(const QFuture &future); void postRunCommand(const FilePath &workingDirectory); - ShellCommand *m_command; + VcsCommand *m_command; QFutureInterface m_futureInterface; }; -VcsCommandDecorator::VcsCommandDecorator(ShellCommand *command) +VcsCommandDecorator::VcsCommandDecorator(VcsCommand *command) : QObject(command) , m_command(command) { @@ -101,24 +101,24 @@ VcsCommandDecorator::VcsCommandDecorator(ShellCommand *command) VcsOutputWindow::setRepository(m_command->defaultWorkingDirectory().toString()); m_command->setDisableUnixTerminal(); - connect(m_command, &ShellCommand::started, this, [this] { - if (m_command->flags() & ShellCommand::ExpectRepoChanges) + connect(m_command, &VcsCommand::started, this, [this] { + if (m_command->flags() & VcsCommand::ExpectRepoChanges) GlobalFileChangeBlocker::instance()->forceBlocked(true); }); - connect(m_command, &ShellCommand::finished, this, [this] { - if (m_command->flags() & ShellCommand::ExpectRepoChanges) + connect(m_command, &VcsCommand::finished, this, [this] { + if (m_command->flags() & VcsCommand::ExpectRepoChanges) GlobalFileChangeBlocker::instance()->forceBlocked(false); }); VcsOutputWindow *outputWindow = VcsOutputWindow::instance(); - connect(m_command, &ShellCommand::append, outputWindow, [outputWindow](const QString &t) { + connect(m_command, &VcsCommand::append, outputWindow, [outputWindow](const QString &t) { outputWindow->append(t); }); - 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, + connect(m_command, &VcsCommand::appendSilently, outputWindow, &VcsOutputWindow::appendSilently); + connect(m_command, &VcsCommand::appendError, outputWindow, &VcsOutputWindow::appendError); + connect(m_command, &VcsCommand::appendCommand, outputWindow, &VcsOutputWindow::appendCommand); + connect(m_command, &VcsCommand::appendMessage, outputWindow, &VcsOutputWindow::appendMessage); + connect(m_command, &VcsCommand::executedAsync, this, &VcsCommandDecorator::addTask); + const auto connection = connect(m_command, &VcsCommand::runCommandFinished, this, &VcsCommandDecorator::postRunCommand); connect(ICore::instance(), &ICore::coreAboutToClose, this, [this, connection] { disconnect(connection); @@ -133,7 +133,7 @@ VcsCommandDecorator::~VcsCommandDecorator() void VcsCommandDecorator::addTask(const QFuture &future) { - if ((m_command->flags() & ShellCommand::SuppressCommandLogging)) + if ((m_command->flags() & VcsCommand::SuppressCommandLogging)) return; const QString name = m_command->displayName(); @@ -149,7 +149,7 @@ void VcsCommandDecorator::addTask(const QFuture &future) void VcsCommandDecorator::postRunCommand(const FilePath &workingDirectory) { - if (!(m_command->flags() & ShellCommand::ExpectRepoChanges)) + if (!(m_command->flags() & VcsCommand::ExpectRepoChanges)) return; // TODO tell the document manager that the directory now received all expected changes // Core::DocumentManager::unexpectDirectoryChange(d->m_workingDirectory); @@ -174,7 +174,7 @@ FilePath VcsBaseClientImpl::vcsBinary() const return m_baseSettings->binaryPath.filePath(); } -ShellCommand *VcsBaseClientImpl::createCommand(const FilePath &workingDirectory, +VcsCommand *VcsBaseClientImpl::createCommand(const FilePath &workingDirectory, VcsBaseEditorWidget *editor, JobOutputBindMode mode) const { @@ -183,32 +183,32 @@ ShellCommand *VcsBaseClientImpl::createCommand(const FilePath &workingDirectory, if (editor) editor->setCommand(cmd); if (mode == VcsWindowOutputBind) { - cmd->addFlags(ShellCommand::ShowStdOut); + cmd->addFlags(VcsCommand::ShowStdOut); if (editor) // assume that the commands output is the important thing - cmd->addFlags(ShellCommand::SilentOutput); + cmd->addFlags(VcsCommand::SilentOutput); } else if (editor) { - connect(cmd, &ShellCommand::stdOutText, editor, &VcsBaseEditorWidget::setPlainText); + connect(cmd, &VcsCommand::stdOutText, editor, &VcsBaseEditorWidget::setPlainText); } return cmd; } -ShellCommand *VcsBaseClientImpl::execBgCommand(const FilePath &workingDirectory, +VcsCommand *VcsBaseClientImpl::execBgCommand(const FilePath &workingDirectory, const QStringList &args, const std::function &outputCallback, unsigned flags) const { - ShellCommand *cmd = createCommand(workingDirectory); - cmd->addFlags(flags | ShellCommand::SuppressCommandLogging - | ShellCommand::SuppressStdErr - | ShellCommand::SuppressFailMessage); + VcsCommand *cmd = createCommand(workingDirectory); + cmd->addFlags(flags | VcsCommand::SuppressCommandLogging + | VcsCommand::SuppressStdErr + | VcsCommand::SuppressFailMessage); cmd->addJob({vcsBinary(), args}); - connect(cmd, &ShellCommand::stdOutText, this, outputCallback); + connect(cmd, &VcsCommand::stdOutText, this, outputCallback); cmd->execute(); return cmd; } -void VcsBaseClientImpl::enqueueJob(ShellCommand *cmd, const QStringList &args, +void VcsBaseClientImpl::enqueueJob(VcsCommand *cmd, const QStringList &args, const ExitCodeInterpreter &interpreter) const { cmd->addJob({vcsBinary(), args}, vcsTimeoutS(), {}, interpreter); @@ -249,7 +249,7 @@ CommandResult VcsBaseClientImpl::vcsFullySynchronousExec(const FilePath &working CommandResult VcsBaseClientImpl::vcsFullySynchronousExec(const FilePath &workingDir, const CommandLine &cmdLine, unsigned flags, int timeoutS, QTextCodec *codec) const { - ShellCommand command(workingDir, processEnvironment()); + VcsCommand command(workingDir, processEnvironment()); new VcsCommandDecorator(&command); command.addFlags(flags); if (codec) @@ -275,12 +275,12 @@ void VcsBaseClientImpl::annotateRevisionRequested(const FilePath &workingDirecto annotate(workingDirectory, file, changeCopy, line); } -ShellCommand *VcsBaseClientImpl::vcsExec(const FilePath &workingDirectory, - const QStringList &arguments, - VcsBaseEditorWidget *editor, bool useOutputToWindow, - unsigned additionalFlags, const QVariant &cookie) const +VcsCommand *VcsBaseClientImpl::vcsExec(const FilePath &workingDirectory, + const QStringList &arguments, + VcsBaseEditorWidget *editor, bool useOutputToWindow, + unsigned additionalFlags, const QVariant &cookie) const { - ShellCommand *command = createCommand(workingDirectory, editor, + VcsCommand *command = createCommand(workingDirectory, editor, useOutputToWindow ? VcsWindowOutputBind : NoOutputBind); command->setCookie(cookie); command->addFlags(additionalFlags); @@ -296,7 +296,7 @@ CommandResult VcsBaseClientImpl::vcsSynchronousExec(const FilePath &workingDir, QTextCodec *outputCodec) const { Environment env = processEnvironment(); - ShellCommand command(workingDir, env.isValid() ? env : Environment::systemEnvironment()); + VcsCommand command(workingDir, env.isValid() ? env : Environment::systemEnvironment()); new VcsCommandDecorator(&command); command.addFlags(flags); command.setCodec(outputCodec); @@ -308,10 +308,10 @@ int VcsBaseClientImpl::vcsTimeoutS() const return m_baseSettings->timeout.value(); } -ShellCommand *VcsBaseClientImpl::createVcsCommand(const FilePath &defaultWorkingDir, - const Environment &environment) +VcsCommand *VcsBaseClientImpl::createVcsCommand(const FilePath &defaultWorkingDir, + const Environment &environment) { - ShellCommand *command = new ShellCommand(defaultWorkingDir, environment); + VcsCommand *command = new VcsCommand(defaultWorkingDir, environment); new VcsCommandDecorator(command); return command; } @@ -421,9 +421,9 @@ bool VcsBaseClient::synchronousPull(const FilePath &workingDir, QStringList args; args << vcsCommandString(PullCommand) << extraOptions << srcLocation; // Disable UNIX terminals to suppress SSH prompting - const unsigned flags = ShellCommand::SshPasswordPrompt - | ShellCommand::ShowStdOut - | ShellCommand::ShowSuccessMessage; + const unsigned flags = VcsCommand::SshPasswordPrompt + | VcsCommand::ShowStdOut + | VcsCommand::ShowSuccessMessage; const bool ok = vcsSynchronousExec(workingDir, args, flags).result() == ProcessResult::FinishedWithSuccess; if (ok) @@ -438,9 +438,9 @@ bool VcsBaseClient::synchronousPush(const FilePath &workingDir, QStringList args; args << vcsCommandString(PushCommand) << extraOptions << dstLocation; // Disable UNIX terminals to suppress SSH prompting - const unsigned flags = ShellCommand::SshPasswordPrompt - | ShellCommand::ShowStdOut - | ShellCommand::ShowSuccessMessage; + const unsigned flags = VcsCommand::SshPasswordPrompt + | VcsCommand::ShowStdOut + | VcsCommand::ShowSuccessMessage; return vcsSynchronousExec(workingDir, args, flags).result() == ProcessResult::FinishedWithSuccess; } @@ -461,7 +461,7 @@ VcsBaseEditorWidget *VcsBaseClient::annotate( VcsBaseEditor::getCodec(source), vcsCmdString.toLatin1().constData(), id); - ShellCommand *cmd = createCommand(workingDir, editor); + VcsCommand *cmd = createCommand(workingDir, editor); cmd->setCookie(lineNumber); enqueueJob(cmd, args); return editor; @@ -503,7 +503,7 @@ void VcsBaseClient::diff(const FilePath &workingDir, const QStringList &files, args << files; QTextCodec *codec = source.isEmpty() ? static_cast(nullptr) : VcsBaseEditor::getCodec(source); - ShellCommand *command = createCommand(workingDir, editor); + VcsCommand *command = createCommand(workingDir, editor); command->setCodec(codec); enqueueJob(command, args, exitCodeInterpreter(DiffCommand)); } @@ -553,9 +553,9 @@ void VcsBaseClient::revertFile(const FilePath &workingDir, QStringList args(vcsCommandString(RevertCommand)); args << revisionSpec(revision) << extraOptions << file; // Indicate repository change or file list - ShellCommand *cmd = createCommand(workingDir); + VcsCommand *cmd = createCommand(workingDir); cmd->setCookie(QStringList(workingDir.pathAppended(file).toString())); - connect(cmd, &ShellCommand::finished, this, [this](bool success, const QVariant &cookie) { + connect(cmd, &VcsCommand::finished, this, [this](bool success, const QVariant &cookie) { if (success) emit changed(cookie); }, Qt::QueuedConnection); @@ -569,9 +569,9 @@ void VcsBaseClient::revertAll(const FilePath &workingDir, QStringList args(vcsCommandString(RevertCommand)); args << revisionSpec(revision) << extraOptions; // Indicate repository change or file list - ShellCommand *cmd = createCommand(workingDir); + VcsCommand *cmd = createCommand(workingDir); cmd->setCookie(QStringList(workingDir.toString())); - connect(cmd, &ShellCommand::finished, this, [this](bool success, const QVariant &cookie) { + connect(cmd, &VcsCommand::finished, this, [this](bool success, const QVariant &cookie) { if (success) emit changed(cookie); }, Qt::QueuedConnection); @@ -585,8 +585,8 @@ void VcsBaseClient::status(const FilePath &workingDir, QStringList args(vcsCommandString(StatusCommand)); args << extraOptions << file; VcsOutputWindow::setRepository(workingDir.toString()); - ShellCommand *cmd = createCommand(workingDir, nullptr, VcsWindowOutputBind); - connect(cmd, &ShellCommand::finished, + VcsCommand *cmd = createCommand(workingDir, nullptr, VcsWindowOutputBind); + connect(cmd, &VcsCommand::finished, VcsOutputWindow::instance(), &VcsOutputWindow::clearRepository, Qt::QueuedConnection); enqueueJob(cmd, args); @@ -596,8 +596,8 @@ void VcsBaseClient::emitParsedStatus(const FilePath &repository, const QStringLi { QStringList args(vcsCommandString(StatusCommand)); args << extraOptions; - ShellCommand *cmd = createCommand(repository); - connect(cmd, &ShellCommand::stdOutText, this, &VcsBaseClient::statusParser); + VcsCommand *cmd = createCommand(repository); + connect(cmd, &VcsCommand::stdOutText, this, &VcsBaseClient::statusParser); enqueueJob(cmd, args); } @@ -670,9 +670,9 @@ void VcsBaseClient::update(const FilePath &repositoryRoot, const QString &revisi { QStringList args(vcsCommandString(UpdateCommand)); args << revisionSpec(revision) << extraOptions; - ShellCommand *cmd = createCommand(repositoryRoot); + VcsCommand *cmd = createCommand(repositoryRoot); cmd->setCookie(repositoryRoot.toString()); - connect(cmd, &ShellCommand::finished, this, [this](bool success, const QVariant &cookie) { + connect(cmd, &VcsCommand::finished, this, [this](bool success, const QVariant &cookie) { if (success) emit changed(cookie); }, Qt::QueuedConnection); @@ -694,9 +694,9 @@ void VcsBaseClient::commit(const FilePath &repositoryRoot, // for example) QStringList args(vcsCommandString(CommitCommand)); args << extraOptions << files; - ShellCommand *cmd = createCommand(repositoryRoot, nullptr, VcsWindowOutputBind); + VcsCommand *cmd = createCommand(repositoryRoot, nullptr, VcsWindowOutputBind); if (!commitMessageFile.isEmpty()) - connect(cmd, &ShellCommand::finished, [commitMessageFile] { QFile(commitMessageFile).remove(); }); + connect(cmd, &VcsCommand::finished, [commitMessageFile] { QFile(commitMessageFile).remove(); }); enqueueJob(cmd, args); } diff --git a/src/plugins/vcsbase/vcsbaseclient.h b/src/plugins/vcsbase/vcsbaseclient.h index e162fff3227..0b4eb9c2a17 100644 --- a/src/plugins/vcsbase/vcsbaseclient.h +++ b/src/plugins/vcsbase/vcsbaseclient.h @@ -44,15 +44,12 @@ class QTextCodec; class QToolBar; QT_END_NAMESPACE -namespace Utils { -class CommandResult; -class ShellCommand; -} - namespace VcsBase { +class CommandResult; class VcsBaseEditorConfig; class VcsBaseEditorWidget; +class VcsCommand; class VCSBASE_EXPORT VcsBaseClientImpl : public QObject { @@ -72,24 +69,24 @@ public: VcsWindowOutputBind }; - static Utils::ShellCommand *createVcsCommand(const Utils::FilePath &defaultWorkingDir, - const Utils::Environment &environment); + static VcsCommand *createVcsCommand(const Utils::FilePath &defaultWorkingDir, + const Utils::Environment &environment); VcsBaseEditorWidget *createVcsEditor(Utils::Id kind, QString title, const QString &source, QTextCodec *codec, const char *registerDynamicProperty, const QString &dynamicPropertyValue) const; - Utils::ShellCommand *createCommand(const Utils::FilePath &workingDirectory, - VcsBaseEditorWidget *editor = nullptr, - JobOutputBindMode mode = NoOutputBind) const; + VcsCommand *createCommand(const Utils::FilePath &workingDirectory, + VcsBaseEditorWidget *editor = nullptr, + JobOutputBindMode mode = NoOutputBind) const; - Utils::ShellCommand *execBgCommand(const Utils::FilePath &workingDirectory, - const QStringList &args, - const std::function &outputCallback, - unsigned flags = 0) const; + VcsCommand *execBgCommand(const Utils::FilePath &workingDirectory, + const QStringList &args, + const std::function &outputCallback, + unsigned flags = 0) const; - void enqueueJob(Utils::ShellCommand *cmd, const QStringList &args, + void enqueueJob(VcsCommand *cmd, const QStringList &args, const Utils::ExitCodeInterpreter &interpreter = {}) const; virtual Utils::Environment processEnvironment() const; @@ -106,20 +103,20 @@ public: static QString stripLastNewline(const QString &in); // Fully synchronous VCS execution (QProcess-based) - Utils::CommandResult vcsFullySynchronousExec(const Utils::FilePath &workingDir, - const QStringList &args, unsigned flags = 0, - int timeoutS = -1, QTextCodec *codec = nullptr) const; - Utils::CommandResult vcsFullySynchronousExec(const Utils::FilePath &workingDir, - const Utils::CommandLine &cmdLine, unsigned flags = 0, - int timeoutS = -1, QTextCodec *codec = nullptr) const; + CommandResult vcsFullySynchronousExec(const Utils::FilePath &workingDir, + const QStringList &args, unsigned flags = 0, + int timeoutS = -1, QTextCodec *codec = nullptr) const; + CommandResult vcsFullySynchronousExec(const Utils::FilePath &workingDir, + const Utils::CommandLine &cmdLine, unsigned flags = 0, + int timeoutS = -1, QTextCodec *codec = nullptr) const; // Simple helper to execute a single command using createCommand and enqueueJob. - Utils::ShellCommand *vcsExec(const Utils::FilePath &workingDirectory, - const QStringList &arguments, - VcsBaseEditorWidget *editor = nullptr, - bool useOutputToWindow = false, - unsigned additionalFlags = 0, - const QVariant &cookie = {}) const; + VcsCommand *vcsExec(const Utils::FilePath &workingDirectory, + const QStringList &arguments, + VcsBaseEditorWidget *editor = nullptr, + bool useOutputToWindow = false, + unsigned additionalFlags = 0, + const QVariant &cookie = {}) const; protected: void resetCachedVcsInfo(const Utils::FilePath &workingDir); @@ -128,10 +125,10 @@ protected: // Synchronous VCS execution using Utils::SynchronousProcess, with // log windows updating (using VcsBasePlugin::runVcs with flags) - Utils::CommandResult vcsSynchronousExec(const Utils::FilePath &workingDir, - const QStringList &args, - unsigned flags = 0, - QTextCodec *outputCodec = nullptr) const; + CommandResult vcsSynchronousExec(const Utils::FilePath &workingDir, + const QStringList &args, + unsigned flags = 0, + QTextCodec *outputCodec = nullptr) const; private: void saveSettings(); diff --git a/src/plugins/vcsbase/vcsbasediffeditorcontroller.cpp b/src/plugins/vcsbase/vcsbasediffeditorcontroller.cpp index 44dc8786173..ea73682131a 100644 --- a/src/plugins/vcsbase/vcsbasediffeditorcontroller.cpp +++ b/src/plugins/vcsbase/vcsbasediffeditorcontroller.cpp @@ -25,16 +25,17 @@ #include "vcsbasediffeditorcontroller.h" #include "vcsbaseclient.h" +#include "vcscommand.h" #include #include + #include #include #include #include #include -#include #include @@ -73,7 +74,7 @@ static void readPatch(QFutureInterface> &futureInterface, class VcsCommandResultProxy : public QObject { Q_OBJECT public: - VcsCommandResultProxy(ShellCommand *command, VcsBaseDiffEditorControllerPrivate *target); + VcsCommandResultProxy(VcsCommand *command, VcsBaseDiffEditorControllerPrivate *target); private: void storeOutput(const QString &output); void commandFinished(bool success); @@ -103,23 +104,23 @@ public: QString m_startupFile; QString m_output; QString m_displayName; - QPointer m_command; + QPointer m_command; QPointer m_commandResultProxy; QFutureWatcher> *m_processWatcher = nullptr; }; ///////////////////// -VcsCommandResultProxy::VcsCommandResultProxy(ShellCommand *command, +VcsCommandResultProxy::VcsCommandResultProxy(VcsCommand *command, VcsBaseDiffEditorControllerPrivate *target) : QObject(target->q) , m_target(target) { - connect(command, &ShellCommand::stdOutText, + connect(command, &VcsCommand::stdOutText, this, &VcsCommandResultProxy::storeOutput); - connect(command, &ShellCommand::finished, + connect(command, &VcsCommand::finished, this, &VcsCommandResultProxy::commandFinished); - connect(command, &ShellCommand::destroyed, + connect(command, &VcsCommand::destroyed, this, &QObject::deleteLater); } diff --git a/src/plugins/vcsbase/vcsbaseeditor.cpp b/src/plugins/vcsbase/vcsbaseeditor.cpp index ab8abed121a..d22b7a274e4 100644 --- a/src/plugins/vcsbase/vcsbaseeditor.cpp +++ b/src/plugins/vcsbase/vcsbaseeditor.cpp @@ -30,6 +30,7 @@ #include "diffandloghighlighter.h" #include "vcsbaseeditorconfig.h" #include "vcsbaseplugin.h" +#include "vcscommand.h" #include #include @@ -52,7 +53,6 @@ #include #include #include -#include #include #include @@ -561,7 +561,7 @@ public: QString m_annotatePreviousRevisionTextFormat; VcsBaseEditorConfig *m_config = nullptr; QList m_textCursorHandlers; - QPointer m_command; + QPointer m_command; VcsBaseEditorWidget::DescribeFunc m_describeFunc = nullptr; ProgressIndicator *m_progressIndicator = nullptr; bool m_fileLogAnnotateEnabled = false; @@ -1408,7 +1408,7 @@ VcsBaseEditorConfig *VcsBaseEditorWidget::editorConfig() const return d->m_config; } -void VcsBaseEditorWidget::setCommand(ShellCommand *command) +void VcsBaseEditorWidget::setCommand(VcsCommand *command) { if (d->m_command) { d->m_command->abort(); @@ -1418,7 +1418,7 @@ void VcsBaseEditorWidget::setCommand(ShellCommand *command) if (command) { d->m_progressIndicator = new ProgressIndicator(ProgressIndicatorSize::Large); d->m_progressIndicator->attachToWidget(this); - connect(command, &ShellCommand::finished, this, &VcsBaseEditorWidget::reportCommandFinished); + connect(command, &VcsCommand::finished, this, &VcsBaseEditorWidget::reportCommandFinished); QTimer::singleShot(100, this, &VcsBaseEditorWidget::showProgressIndicator); } } diff --git a/src/plugins/vcsbase/vcsbaseeditor.h b/src/plugins/vcsbase/vcsbaseeditor.h index 4c536305575..6a4ea15ea3d 100644 --- a/src/plugins/vcsbase/vcsbaseeditor.h +++ b/src/plugins/vcsbase/vcsbaseeditor.h @@ -36,8 +36,6 @@ QT_BEGIN_NAMESPACE class QTextCursor; QT_END_NAMESPACE -namespace Utils { class ShellCommand; } - namespace VcsBase { namespace Internal { @@ -48,6 +46,7 @@ class VcsBaseEditorWidgetPrivate; class BaseAnnotationHighlighter; class VcsBaseEditorConfig; class VcsBaseEditorWidget; +class VcsCommand; class VcsEditorFactory; // Documentation inside @@ -213,7 +212,7 @@ public: void setEditorConfig(VcsBaseEditorConfig *config); VcsBaseEditorConfig *editorConfig() const; - void setCommand(Utils::ShellCommand *command); + void setCommand(VcsCommand *command); virtual void setPlainText(const QString &text); diff --git a/src/libs/utils/shellcommand.cpp b/src/plugins/vcsbase/vcscommand.cpp similarity index 80% rename from src/libs/utils/shellcommand.cpp rename to src/plugins/vcsbase/vcscommand.cpp index 0e598e1f40e..faca33c759f 100644 --- a/src/libs/utils/shellcommand.cpp +++ b/src/plugins/vcsbase/vcscommand.cpp @@ -23,12 +23,12 @@ ** ****************************************************************************/ -#include "shellcommand.h" +#include "vcscommand.h" -#include "environment.h" -#include "qtcassert.h" -#include "qtcprocess.h" -#include "runextensions.h" +#include +#include +#include +#include #include #include @@ -56,10 +56,12 @@ when a progress string is detected. */ -namespace Utils { +using namespace Utils; + +namespace VcsBase { namespace Internal { -class ShellCommandPrivate +class VcsCommandPrivate { public: struct Job { @@ -72,16 +74,16 @@ public: int timeoutS; }; - ShellCommandPrivate(const FilePath &defaultWorkingDirectory, const Environment &environment) + VcsCommandPrivate(const FilePath &defaultWorkingDirectory, const Environment &environment) : m_defaultWorkingDirectory(defaultWorkingDirectory), m_environment(environment) {} - ~ShellCommandPrivate() { delete m_progressParser; } + ~VcsCommandPrivate() { delete m_progressParser; } Environment environment() { - if (!(m_flags & ShellCommand::ForceCLocale)) + if (!(m_flags & VcsCommand::ForceCLocale)) return m_environment; m_environment.set("LANG", "C"); @@ -107,7 +109,7 @@ public: bool m_disableUnixTerminal = false; }; -ShellCommandPrivate::Job::Job(const FilePath &wd, const CommandLine &command, +VcsCommandPrivate::Job::Job(const FilePath &wd, const CommandLine &command, int t, const ExitCodeInterpreter &interpreter) : workingDirectory(wd), command(command), @@ -121,23 +123,23 @@ ShellCommandPrivate::Job::Job(const FilePath &wd, const CommandLine &command, } // namespace Internal -ShellCommand::ShellCommand(const FilePath &workingDirectory, const Environment &environment) : - d(new Internal::ShellCommandPrivate(workingDirectory, environment)) +VcsCommand::VcsCommand(const FilePath &workingDirectory, const Environment &environment) : + d(new Internal::VcsCommandPrivate(workingDirectory, environment)) { - connect(&d->m_watcher, &QFutureWatcher::canceled, this, &ShellCommand::cancel); + connect(&d->m_watcher, &QFutureWatcher::canceled, this, &VcsCommand::cancel); } -ShellCommand::~ShellCommand() +VcsCommand::~VcsCommand() { delete d; } -QString ShellCommand::displayName() const +QString VcsCommand::displayName() const { if (!d->m_displayName.isEmpty()) return d->m_displayName; if (!d->m_jobs.isEmpty()) { - const Internal::ShellCommandPrivate::Job &job = d->m_jobs.at(0); + const Internal::VcsCommandPrivate::Job &job = d->m_jobs.at(0); QString result = job.command.executable().baseName(); if (!result.isEmpty()) result[0] = result.at(0).toTitleCase(); @@ -152,98 +154,98 @@ QString ShellCommand::displayName() const return tr("Unknown"); } -void ShellCommand::setDisplayName(const QString &name) +void VcsCommand::setDisplayName(const QString &name) { d->m_displayName = name; } -const FilePath &ShellCommand::defaultWorkingDirectory() const +const FilePath &VcsCommand::defaultWorkingDirectory() const { return d->m_defaultWorkingDirectory; } -Environment ShellCommand::environment() const +Environment VcsCommand::environment() const { return d->m_environment; } -void ShellCommand::setEnvironment(const Environment &env) +void VcsCommand::setEnvironment(const Environment &env) { d->m_environment = env; } -int ShellCommand::defaultTimeoutS() const +int VcsCommand::defaultTimeoutS() const { return d->m_defaultTimeoutS; } -void ShellCommand::setDefaultTimeoutS(int timeout) +void VcsCommand::setDefaultTimeoutS(int timeout) { d->m_defaultTimeoutS = timeout; } -unsigned ShellCommand::flags() const +unsigned VcsCommand::flags() const { return d->m_flags; } -void ShellCommand::addFlags(unsigned f) +void VcsCommand::addFlags(unsigned f) { d->m_flags |= f; } -void ShellCommand::addJob(const CommandLine &command, +void VcsCommand::addJob(const CommandLine &command, const FilePath &workingDirectory, const ExitCodeInterpreter &interpreter) { addJob(command, defaultTimeoutS(), workingDirectory, interpreter); } -void ShellCommand::addJob(const CommandLine &command, int timeoutS, +void VcsCommand::addJob(const CommandLine &command, int timeoutS, const FilePath &workingDirectory, const ExitCodeInterpreter &interpreter) { - d->m_jobs.push_back(Internal::ShellCommandPrivate::Job(workDirectory(workingDirectory), command, + d->m_jobs.push_back(Internal::VcsCommandPrivate::Job(workDirectory(workingDirectory), command, timeoutS, interpreter)); } -void ShellCommand::execute() +void VcsCommand::execute() { if (d->m_jobs.empty()) return; - QFuture task = runAsync(&ShellCommand::run, this); + QFuture task = runAsync(&VcsCommand::run, this); d->m_watcher.setFuture(task); emit executedAsync(task); } -void ShellCommand::abort() +void VcsCommand::abort() { d->m_aborted = true; d->m_watcher.future().cancel(); } -void ShellCommand::cancel() +void VcsCommand::cancel() { emit terminate(); } -int ShellCommand::timeoutS() const +int VcsCommand::timeoutS() const { return std::accumulate(d->m_jobs.cbegin(), d->m_jobs.cend(), 0, - [](int sum, const Internal::ShellCommandPrivate::Job &job) { + [](int sum, const Internal::VcsCommandPrivate::Job &job) { return sum + job.timeoutS; }); } -FilePath ShellCommand::workDirectory(const FilePath &wd) const +FilePath VcsCommand::workDirectory(const FilePath &wd) const { if (!wd.isEmpty()) return wd; return defaultWorkingDirectory(); } -void ShellCommand::run(QFutureInterface &future) +void VcsCommand::run(QFutureInterface &future) { // Check that the binary path is not empty QTC_ASSERT(!d->m_jobs.isEmpty(), return); @@ -259,7 +261,7 @@ void ShellCommand::run(QFutureInterface &future) const int count = d->m_jobs.size(); bool lastExecSuccess = true; for (int j = 0; j < count; j++) { - const Internal::ShellCommandPrivate::Job &job = d->m_jobs.at(j); + const Internal::VcsCommandPrivate::Job &job = d->m_jobs.at(j); const CommandResult result = runCommand(job.command, job.workingDirectory, job.timeoutS, job.exitCodeInterpreter); stdOut += result.cleanedStdOut(); @@ -289,7 +291,7 @@ void ShellCommand::run(QFutureInterface &future) this->deleteLater(); } -CommandResult ShellCommand::runCommand(const CommandLine &command, const FilePath &workingDirectory, +CommandResult VcsCommand::runCommand(const CommandLine &command, const FilePath &workingDirectory, int timeoutS, const ExitCodeInterpreter &interpreter) { QtcProcess proc; @@ -336,7 +338,7 @@ CommandResult ShellCommand::runCommand(const CommandLine &command, const FilePat return CommandResult(proc); } -void ShellCommand::runFullySynchronous(QtcProcess &process) +void VcsCommand::runFullySynchronous(QtcProcess &process) { process.runBlocking(); @@ -355,9 +357,9 @@ void ShellCommand::runFullySynchronous(QtcProcess &process) } } -void ShellCommand::runSynchronous(QtcProcess &process) +void VcsCommand::runSynchronous(QtcProcess &process) { - connect(this, &ShellCommand::terminate, &process, [&process] { + connect(this, &VcsCommand::terminate, &process, [&process] { process.stop(); process.waitForFinished(); }); @@ -392,44 +394,44 @@ void ShellCommand::runSynchronous(QtcProcess &process) process.runBlocking(EventLoopMode::On); } -const QVariant &ShellCommand::cookie() const +const QVariant &VcsCommand::cookie() const { return d->m_cookie; } -void ShellCommand::setCookie(const QVariant &cookie) +void VcsCommand::setCookie(const QVariant &cookie) { d->m_cookie = cookie; } -QTextCodec *ShellCommand::codec() const +QTextCodec *VcsCommand::codec() const { return d->m_codec; } -void ShellCommand::setCodec(QTextCodec *codec) +void VcsCommand::setCodec(QTextCodec *codec) { d->m_codec = codec; } //! Use \a parser to parse progress data from stdout. Command takes ownership of \a parser -void ShellCommand::setProgressParser(ProgressParser *parser) +void VcsCommand::setProgressParser(ProgressParser *parser) { QTC_ASSERT(!d->m_progressParser, return); d->m_progressParser = parser; } -bool ShellCommand::hasProgressParser() const +bool VcsCommand::hasProgressParser() const { return d->m_progressParser; } -void ShellCommand::setProgressiveOutput(bool progressive) +void VcsCommand::setProgressiveOutput(bool progressive) { d->m_progressiveOutput = progressive; } -void ShellCommand::setDisableUnixTerminal() +void VcsCommand::setDisableUnixTerminal() { d->m_disableUnixTerminal = true; } @@ -467,4 +469,4 @@ CommandResult::CommandResult(const QtcProcess &process) , m_rawStdOut(process.rawStdOut()) {} -} // namespace Utils +} // namespace VcsBase diff --git a/src/libs/utils/shellcommand.h b/src/plugins/vcsbase/vcscommand.h similarity index 76% rename from src/libs/utils/shellcommand.h rename to src/plugins/vcsbase/vcscommand.h index bcc8a80ecdd..e2d77498c51 100644 --- a/src/libs/utils/shellcommand.h +++ b/src/plugins/vcsbase/vcscommand.h @@ -25,10 +25,10 @@ #pragma once -#include "utils_global.h" +#include "vcsbase_global.h" -#include "filepath.h" -#include "processenums.h" +#include +#include #include @@ -43,14 +43,16 @@ class QTextCodec; QT_END_NAMESPACE namespace Utils { - class CommandLine; class Environment; class QtcProcess; +} -namespace Internal { class ShellCommandPrivate; } +namespace VcsBase { -class QTCREATOR_UTILS_EXPORT ProgressParser +namespace Internal { class VcsCommandPrivate; } + +class VCSBASE_EXPORT ProgressParser { public: ProgressParser(); @@ -65,16 +67,16 @@ private: QFutureInterface *m_future; QMutex *m_futureMutex = nullptr; - friend class ShellCommand; + friend class VcsCommand; }; -class QTCREATOR_UTILS_EXPORT CommandResult +class VCSBASE_EXPORT CommandResult { public: CommandResult() = default; - CommandResult(const QtcProcess &process); + CommandResult(const Utils::QtcProcess &process); - ProcessResult result() const { return m_result; } + Utils::ProcessResult result() const { return m_result; } int exitCode() const { return m_exitCode; } QString exitMessage() const { return m_exitMessage; } @@ -84,7 +86,7 @@ public: QByteArray rawStdOut() const { return m_rawStdOut; } private: - ProcessResult m_result = ProcessResult::StartFailed; + Utils::ProcessResult m_result = Utils::ProcessResult::StartFailed; int m_exitCode = 0; QString m_exitMessage; @@ -94,7 +96,7 @@ private: QByteArray m_rawStdOut; }; -class QTCREATOR_UTILS_EXPORT ShellCommand final : public QObject +class VCSBASE_EXPORT VcsCommand final : public QObject { Q_OBJECT @@ -118,23 +120,23 @@ public: }; - ShellCommand(const FilePath &workingDirectory, const Environment &environment); - ~ShellCommand() override; + VcsCommand(const Utils::FilePath &workingDirectory, const Utils::Environment &environment); + ~VcsCommand() override; QString displayName() const; void setDisplayName(const QString &name); - const FilePath &defaultWorkingDirectory() const; + const Utils::FilePath &defaultWorkingDirectory() const; - Environment environment() const; - void setEnvironment(const Environment &env); + Utils::Environment environment() const; + void setEnvironment(const Utils::Environment &env); - void addJob(const CommandLine &command, - const FilePath &workingDirectory = {}, - const ExitCodeInterpreter &interpreter = {}); - void addJob(const CommandLine &command, int timeoutS, - const FilePath &workingDirectory = {}, - const ExitCodeInterpreter &interpreter = {}); + void addJob(const Utils::CommandLine &command, + const Utils::FilePath &workingDirectory = {}, + const Utils::ExitCodeInterpreter &interpreter = {}); + void addJob(const Utils::CommandLine &command, int timeoutS, + const Utils::FilePath &workingDirectory = {}, + const Utils::ExitCodeInterpreter &interpreter = {}); void execute(); // Execute tasks asynchronously! void abort(); @@ -157,8 +159,9 @@ public: // This is called once per job in a thread. // When called from the UI thread it will execute fully synchronously, so no signals will // be triggered! - CommandResult runCommand(const CommandLine &command, const FilePath &workingDirectory = {}, - int timeoutS = 10, const ExitCodeInterpreter &interpreter = {}); + CommandResult runCommand(const Utils::CommandLine &command, + const Utils::FilePath &workingDirectory = {}, + int timeoutS = 10, const Utils::ExitCodeInterpreter &interpreter = {}); void cancel(); @@ -184,15 +187,15 @@ signals: void runCommandFinished(const Utils::FilePath &workingDirectory); private: - FilePath workDirectory(const FilePath &wd) const; + Utils::FilePath workDirectory(const Utils::FilePath &wd) const; void run(QFutureInterface &future); // Run without a event loop in fully blocking mode. No signals will be delivered. - void runFullySynchronous(QtcProcess &proc); + void runFullySynchronous(Utils::QtcProcess &proc); // Run with an event loop. Signals will be delivered. - void runSynchronous(QtcProcess &proc); + void runSynchronous(Utils::QtcProcess &proc); - class Internal::ShellCommandPrivate *const d; + class Internal::VcsCommandPrivate *const d; }; } // namespace Utils diff --git a/src/plugins/vcsbase/wizard/vcscommandpage.cpp b/src/plugins/vcsbase/wizard/vcscommandpage.cpp index c57880a801f..717fb963859 100644 --- a/src/plugins/vcsbase/wizard/vcscommandpage.cpp +++ b/src/plugins/vcsbase/wizard/vcscommandpage.cpp @@ -24,6 +24,7 @@ ****************************************************************************/ #include "vcscommandpage.h" +#include "vcscommand.h" #include #include @@ -32,12 +33,18 @@ #include #include +#include #include -#include +#include -#include +#include +#include #include +#include +#include +#include #include +#include using namespace Core; using namespace ProjectExplorer; @@ -61,6 +68,122 @@ static char JOB_ARGUMENTS[] = "arguments"; static char JOB_TIME_OUT[] = "timeoutFactor"; static char JOB_ENABLED[] = "enabled"; + +/*! + \class VcsBase::ShellCommandPage + + \brief The ShellCommandPage implements a page showing the + progress of a \c ShellCommand. + + Turns complete when the command succeeds. +*/ + +ShellCommandPage::ShellCommandPage(QWidget *parent) : + WizardPage(parent), + m_startedStatus(tr("Command started...")) +{ + resize(264, 200); + auto verticalLayout = new QVBoxLayout(this); + m_logPlainTextEdit = new QPlainTextEdit; + m_formatter = new OutputFormatter; + m_logPlainTextEdit->setReadOnly(true); + m_formatter->setPlainTextEdit(m_logPlainTextEdit); + + verticalLayout->addWidget(m_logPlainTextEdit); + + m_statusLabel = new QLabel; + verticalLayout->addWidget(m_statusLabel); + setTitle(tr("Run Command")); +} + +ShellCommandPage::~ShellCommandPage() +{ + QTC_ASSERT(m_state != Running, QApplication::restoreOverrideCursor()); + delete m_formatter; +} + +void ShellCommandPage::setStartedStatus(const QString &startedStatus) +{ + m_startedStatus = startedStatus; +} + +void ShellCommandPage::start(VcsCommand *command) +{ + if (!command) { + m_logPlainTextEdit->setPlainText(tr("No job running, please abort.")); + return; + } + + QTC_ASSERT(m_state != Running, return); + m_command = command; + command->setProgressiveOutput(true); + connect(command, &VcsCommand::stdOutText, this, [this](const QString &text) { + m_formatter->appendMessage(text, StdOutFormat); + }); + connect(command, &VcsCommand::stdErrText, this, [this](const QString &text) { + m_formatter->appendMessage(text, StdErrFormat); + }); + connect(command, &VcsCommand::finished, this, &ShellCommandPage::slotFinished); + QApplication::setOverrideCursor(Qt::WaitCursor); + m_logPlainTextEdit->clear(); + m_overwriteOutput = false; + m_statusLabel->setText(m_startedStatus); + m_statusLabel->setPalette(QPalette()); + m_state = Running; + command->execute(); + + wizard()->button(QWizard::BackButton)->setEnabled(false); +} + +void ShellCommandPage::slotFinished(bool success, const QVariant &) +{ + QTC_ASSERT(m_state == Running, return); + + QString message; + QPalette palette; + + if (success) { + m_state = Succeeded; + message = tr("Succeeded."); + palette.setColor(QPalette::WindowText, creatorTheme()->color(Theme::TextColorNormal).name()); + } else { + m_state = Failed; + message = tr("Failed."); + palette.setColor(QPalette::WindowText, creatorTheme()->color(Theme::TextColorError).name()); + } + + m_statusLabel->setText(message); + m_statusLabel->setPalette(palette); + + QApplication::restoreOverrideCursor(); + wizard()->button(QWizard::BackButton)->setEnabled(true); + + if (success) + emit completeChanged(); + emit finished(success); +} + +void ShellCommandPage::terminate() +{ + if (m_command) + m_command->cancel(); +} + +bool ShellCommandPage::handleReject() +{ + if (!isRunning()) + return false; + + terminate(); + return true; +} + +bool ShellCommandPage::isComplete() const +{ + return m_state == Succeeded; +} + + // ---------------------------------------------------------------------- // VcsCommandPageFactory: // ---------------------------------------------------------------------- @@ -289,8 +412,8 @@ void VcsCommandPage::delayedInitialize() extraArgs << tmp; } - ShellCommand *command = vc->createInitialCheckoutCommand(repo, FilePath::fromString(base), - name, extraArgs); + VcsCommand *command = vc->createInitialCheckoutCommand(repo, FilePath::fromString(base), + name, extraArgs); for (const JobData &job : qAsConst(m_additionalJobs)) { QTC_ASSERT(!job.job.isEmpty(), continue); diff --git a/src/plugins/vcsbase/wizard/vcscommandpage.h b/src/plugins/vcsbase/wizard/vcscommandpage.h index 38070fba3be..1432e582317 100644 --- a/src/plugins/vcsbase/wizard/vcscommandpage.h +++ b/src/plugins/vcsbase/wizard/vcscommandpage.h @@ -30,13 +30,24 @@ #include #include -#include +#include #include -namespace Utils { class FilePath; } +QT_BEGIN_NAMESPACE +class QPlainTextEdit; +class QLabel; +QT_END_NAMESPACE + +namespace Utils { +class FilePath; +class OutputFormatter; +} namespace VcsBase { + +class VcsCommand; + namespace Internal { class VcsCommandPageFactory : public ProjectExplorer::JsonWizardPageFactory @@ -51,7 +62,44 @@ public: bool validateData(Utils::Id typeId, const QVariant &data, QString *errorMessage) override; }; -class VcsCommandPage : public Utils::ShellCommandPage +class ShellCommandPage : public Utils::WizardPage +{ + Q_OBJECT + +public: + enum State { Idle, Running, Failed, Succeeded }; + + explicit ShellCommandPage(QWidget *parent = nullptr); + ~ShellCommandPage() override; + + void setStartedStatus(const QString &startedStatus); + void start(VcsCommand *command); + + bool isComplete() const override; + bool isRunning() const{ return m_state == Running; } + + void terminate(); + + bool handleReject() override; + +signals: + void finished(bool success); + +private: + void slotFinished(bool success, const QVariant &cookie); + + QPlainTextEdit *m_logPlainTextEdit; + Utils::OutputFormatter *m_formatter; + QLabel *m_statusLabel; + + VcsCommand *m_command = nullptr; + QString m_startedStatus; + bool m_overwriteOutput = false; + + State m_state = Idle; +}; + +class VcsCommandPage : public ShellCommandPage { Q_OBJECT