Move ShellCommand into VcsBase plugin

Rename it to VcsCommand. Move also ShellCommandPage into
VcsBase plugin.

Change-Id: I335ac47e3090f2be497643ebcda0eaad2987ac81
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
Reviewed-by: Orgad Shaneh <orgads@gmail.com>
This commit is contained in:
Jarek Kobus
2022-08-01 10:49:13 +02:00
parent 61adea0cfd
commit 60302debd7
38 changed files with 613 additions and 663 deletions

View File

@@ -142,8 +142,6 @@ add_qtc_library(Utils
settingsaccessor.cpp settingsaccessor.h settingsaccessor.cpp settingsaccessor.h
settingsselector.cpp settingsselector.h settingsselector.cpp settingsselector.h
settingsutils.h settingsutils.h
shellcommand.cpp shellcommand.h
shellcommandpage.cpp shellcommandpage.h
singleton.cpp singleton.h singleton.cpp singleton.h
sizedarray.h sizedarray.h
smallstring.h smallstring.h

View File

@@ -1707,7 +1707,7 @@ QString QtcProcess::stdOut() const
QString QtcProcess::stdErr() const QString QtcProcess::stdErr() const
{ {
// FIXME: The tighter check below is actually good theoretically, but currently // 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. // is not trivial. So weaken it a bit for now.
//QTC_CHECK(d->m_stdErr.keepRawData); //QTC_CHECK(d->m_stdErr.keepRawData);
QTC_CHECK(d->m_stdErr.keepRawData || d->m_stdErr.rawData.isEmpty()); QTC_CHECK(d->m_stdErr.keepRawData || d->m_stdErr.rawData.isEmpty());

View File

@@ -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 <QAbstractButton>
#include <QApplication>
#include <QLabel>
#include <QPlainTextEdit>
#include <QVBoxLayout>
/*!
\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

View File

@@ -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

View File

@@ -269,10 +269,6 @@ Project {
"settingsselector.cpp", "settingsselector.cpp",
"settingsselector.h", "settingsselector.h",
"settingsutils.h", "settingsutils.h",
"shellcommand.cpp",
"shellcommand.h",
"shellcommandpage.cpp",
"shellcommandpage.h",
"singleton.cpp", "singleton.cpp",
"singleton.h", "singleton.h",
"sizedarray.h", "sizedarray.h",

View File

@@ -27,11 +27,11 @@
#include "constants.h" #include "constants.h"
#include <vcsbase/vcsbaseplugin.h> #include <vcsbase/vcsbaseplugin.h>
#include <vcsbase/vcsoutputwindow.h>
#include <vcsbase/vcsbaseeditorconfig.h> #include <vcsbase/vcsbaseeditorconfig.h>
#include <vcsbase/vcscommand.h>
#include <vcsbase/vcsoutputwindow.h>
#include <utils/hostosinfo.h> #include <utils/hostosinfo.h>
#include <utils/shellcommand.h>
#include <QDir> #include <QDir>
#include <QFileInfo> #include <QFileInfo>

View File

@@ -50,7 +50,6 @@
#include <utils/environment.h> #include <utils/environment.h>
#include <utils/parameteraction.h> #include <utils/parameteraction.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/shellcommand.h>
#include <utils/stringutils.h> #include <utils/stringutils.h>
#include <vcsbase/basevcseditorfactory.h> #include <vcsbase/basevcseditorfactory.h>
@@ -60,6 +59,7 @@
#include <vcsbase/vcsbaseeditor.h> #include <vcsbase/vcsbaseeditor.h>
#include <vcsbase/vcsbaseplugin.h> #include <vcsbase/vcsbaseplugin.h>
#include <vcsbase/vcsbasesubmiteditor.h> #include <vcsbase/vcsbasesubmiteditor.h>
#include <vcsbase/vcscommand.h>
#include <vcsbase/vcsoutputwindow.h> #include <vcsbase/vcsoutputwindow.h>
#include <QAction> #include <QAction>
@@ -162,10 +162,10 @@ public:
void vcsAnnotate(const Utils::FilePath &file, int line) final; 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); } void vcsDescribe(const Utils::FilePath &source, const QString &id) final { m_client.view(source.toString(), id); }
ShellCommand *createInitialCheckoutCommand(const QString &url, VcsCommand *createInitialCheckoutCommand(const QString &url,
const Utils::FilePath &baseDirectory, const Utils::FilePath &baseDirectory,
const QString &localName, const QString &localName,
const QStringList &extraArgs) final; const QStringList &extraArgs) final;
// To be connected to the VCSTask's success signal to emit the repository/ // To be connected to the VCSTask's success signal to emit the repository/
// files changed signals according to the variant's type: // 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); m_client.annotate(file.parentDir(), file.fileName(), QString(), line);
} }
ShellCommand *BazaarPluginPrivate::createInitialCheckoutCommand(const QString &url, VcsCommand *BazaarPluginPrivate::createInitialCheckoutCommand(const QString &url,
const FilePath &baseDirectory, const FilePath &baseDirectory,
const QString &localName, const QString &localName,
const QStringList &extraArgs) const QStringList &extraArgs)
{ {
QStringList args; QStringList args;
args << m_client.vcsCommandString(BazaarClient::CloneCommand) args << m_client.vcsCommandString(BazaarClient::CloneCommand)

View File

@@ -62,7 +62,6 @@
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/qtcprocess.h> #include <utils/qtcprocess.h>
#include <utils/runextensions.h> #include <utils/runextensions.h>
#include <utils/shellcommand.h>
#include <utils/stringutils.h> #include <utils/stringutils.h>
#include <utils/temporarydirectory.h> #include <utils/temporarydirectory.h>
@@ -73,6 +72,7 @@
#include <vcsbase/vcsoutputwindow.h> #include <vcsbase/vcsoutputwindow.h>
#include <vcsbase/vcsbasesubmiteditor.h> #include <vcsbase/vcsbasesubmiteditor.h>
#include <vcsbase/vcsbaseplugin.h> #include <vcsbase/vcsbaseplugin.h>
#include <vcsbase/vcscommand.h>
#include <QAction> #include <QAction>
#include <QDebug> #include <QDebug>
@@ -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_CHECKIN_ALL[] = "ClearCase.CheckInAll";
static const char CMD_ID_STATUS[] = "ClearCase.Status"; static const char CMD_ID_STATUS[] = "ClearCase.Status";
const int s_silentRun = ShellCommand::NoOutput | ShellCommand::FullySynchronously; const int s_silentRun = VcsCommand::NoOutput | VcsCommand::FullySynchronously;
const int s_verboseRun = ShellCommand::ShowStdOut | ShellCommand::FullySynchronously; const int s_verboseRun = VcsCommand::ShowStdOut | VcsCommand::FullySynchronously;
class ClearCaseResponse class ClearCaseResponse
{ {
@@ -1538,7 +1538,7 @@ void ClearCasePluginPrivate::ccUpdate(const FilePath &workingDir, const QStringL
if (!relativePaths.isEmpty()) if (!relativePaths.isEmpty())
args.append(relativePaths); args.append(relativePaths);
const ClearCaseResponse response = const ClearCaseResponse response =
runCleartool(workingDir, args, m_settings.longTimeOutS(), ShellCommand::ShowStdOut); runCleartool(workingDir, args, m_settings.longTimeOutS(), VcsCommand::ShowStdOut);
if (!response.error) if (!response.error)
emit repositoryChanged(workingDir); emit repositoryChanged(workingDir);
} }
@@ -1793,7 +1793,7 @@ bool ClearCasePluginPrivate::vcsOpen(const FilePath &workingDir, const QString &
} }
args << file; args << file;
ClearCaseResponse response = runCleartool(topLevel, args, m_settings.timeOutS, ClearCaseResponse response = runCleartool(topLevel, args, m_settings.timeOutS,
s_verboseRun | ShellCommand::SuppressStdErr); s_verboseRun | VcsCommand::SuppressStdErr);
if (response.error) { if (response.error) {
if (response.stdErr.contains(QLatin1String("Versions other than the selected version"))) { if (response.stdErr.contains(QLatin1String("Versions other than the selected version"))) {
VersionSelector selector(file, response.stdErr); VersionSelector selector(file, response.stdErr);
@@ -1833,7 +1833,7 @@ bool ClearCasePluginPrivate::vcsSetActivity(const FilePath &workingDir, const QS
QStringList args; QStringList args;
args << QLatin1String("setactivity") << activity; args << QLatin1String("setactivity") << activity;
const ClearCaseResponse actResponse = const ClearCaseResponse actResponse =
runCleartool(workingDir, args, m_settings.timeOutS, ShellCommand::ShowStdOut); runCleartool(workingDir, args, m_settings.timeOutS, VcsCommand::ShowStdOut);
if (actResponse.error) { if (actResponse.error) {
QMessageBox::warning(ICore::dialogParent(), title, QMessageBox::warning(ICore::dialogParent(), title,
tr("Set current activity failed: %1").arg(actResponse.message), QMessageBox::Ok); 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); blockers.append(fcb);
} }
const ClearCaseResponse response = 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 \\\"([^\"]*)\\\""); const QRegularExpression checkedIn("Checked in \\\"([^\"]*)\\\"");
QRegularExpressionMatch match = checkedIn.match(response.stdOut); QRegularExpressionMatch match = checkedIn.match(response.stdOut);
bool anySucceeded = false; bool anySucceeded = false;

View File

@@ -88,7 +88,7 @@ FilePaths IVersionControl::additionalToolsPath() const
return {}; return {};
} }
ShellCommand *IVersionControl::createInitialCheckoutCommand(const QString &url, VcsBase::VcsCommand *IVersionControl::createInitialCheckoutCommand(const QString &url,
const Utils::FilePath &baseDirectory, const Utils::FilePath &baseDirectory,
const QString &localName, const QString &localName,
const QStringList &extraArgs) const QStringList &extraArgs)

View File

@@ -38,7 +38,7 @@
QT_FORWARD_DECLARE_CLASS(QMenu); QT_FORWARD_DECLARE_CLASS(QMenu);
namespace Utils { class ShellCommand; } namespace VcsBase { class VcsCommand; }
namespace Core { namespace Core {
@@ -224,12 +224,12 @@ public:
virtual Utils::FilePaths additionalToolsPath() const; 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 new subdirectory with \a localName will be created.
* *
* \a extraArgs are passed on to the command being run. * \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 Utils::FilePath &baseDirectory,
const QString &localName, const QString &localName,
const QStringList &extraArgs); const QStringList &extraArgs);

View File

@@ -37,6 +37,7 @@
#include <vcsbase/vcsbaseeditor.h> #include <vcsbase/vcsbaseeditor.h>
#include <vcsbase/vcsbaseeditorconfig.h> #include <vcsbase/vcsbaseeditorconfig.h>
#include <vcsbase/vcsbaseplugin.h> #include <vcsbase/vcsbaseplugin.h>
#include <vcsbase/vcscommand.h>
#include <vcsbase/vcsoutputwindow.h> #include <vcsbase/vcsoutputwindow.h>
#include <texteditor/textdocument.h> #include <texteditor/textdocument.h>
@@ -58,7 +59,6 @@
#include <utils/fileutils.h> #include <utils/fileutils.h>
#include <utils/parameteraction.h> #include <utils/parameteraction.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/shellcommand.h>
#include <utils/stringutils.h> #include <utils/stringutils.h>
#include <QAction> #include <QAction>
@@ -113,7 +113,7 @@ const char CVS_SUBMIT_MIMETYPE[] = "text/vnd.qtcreator.cvs.submit";
const char CVSCOMMITEDITOR_ID[] = "CVS Commit Editor"; const char CVSCOMMITEDITOR_ID[] = "CVS Commit Editor";
const char CVSCOMMITEDITOR_DISPLAY_NAME[] = QT_TRANSLATE_NOOP("VCS", "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 class CvsResponse
{ {
@@ -253,10 +253,10 @@ public:
QString vcsOpenText() const final; QString vcsOpenText() const final;
ShellCommand *createInitialCheckoutCommand(const QString &url, VcsCommand *createInitialCheckoutCommand(const QString &url,
const Utils::FilePath &baseDirectory, const Utils::FilePath &baseDirectory,
const QString &localName, const QString &localName,
const QStringList &extraArgs) final; const QStringList &extraArgs) final;
/// ///
@@ -474,10 +474,10 @@ QString CvsPluginPrivate::vcsOpenText() const
return tr("&Edit"); return tr("&Edit");
} }
ShellCommand *CvsPluginPrivate::createInitialCheckoutCommand(const QString &url, VcsCommand *CvsPluginPrivate::createInitialCheckoutCommand(const QString &url,
const Utils::FilePath &baseDirectory, const Utils::FilePath &baseDirectory,
const QString &localName, const QString &localName,
const QStringList &extraArgs) const QStringList &extraArgs)
{ {
QTC_ASSERT(localName == url, return nullptr); 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. // where we are, so, have stdout/stderr channels merged.
QStringList args = QStringList(QLatin1String("status")); QStringList args = QStringList(QLatin1String("status"));
const CvsResponse response = 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) if (response.result != CvsResponse::Ok)
return; return;
// Get list of added/modified/deleted files and purge out undesired ones // 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); args.append(file);
const CvsResponse response = const CvsResponse response =
runCvs(workingDir, args, m_settings.timeout.value(), runCvs(workingDir, args, m_settings.timeout.value(),
ShellCommand::SshPasswordPrompt, codec); VcsCommand::SshPasswordPrompt, codec);
if (response.result != CvsResponse::Ok) if (response.result != CvsResponse::Ok)
return; return;
@@ -1198,7 +1198,7 @@ void CvsPluginPrivate::annotate(const FilePath &workingDir, const QString &file,
args << QLatin1String("-r") << revision; args << QLatin1String("-r") << revision;
args << file; args << file;
const CvsResponse response = runCvs(workingDir, args, m_settings.timeout.value(), const CvsResponse response = runCvs(workingDir, args, m_settings.timeout.value(),
ShellCommand::SshPasswordPrompt, codec); VcsCommand::SshPasswordPrompt, codec);
if (response.result != CvsResponse::Ok) if (response.result != CvsResponse::Ok)
return; return;
@@ -1300,7 +1300,7 @@ bool CvsPluginPrivate::describe(const FilePath &toplevel, const QString &file, c
QStringList args; QStringList args;
args << QLatin1String("log") << (QLatin1String("-r") + changeNr) << file; args << QLatin1String("log") << (QLatin1String("-r") + changeNr) << file;
const CvsResponse logResponse = runCvs(toplevel, args, m_settings.timeout.value(), const CvsResponse logResponse = runCvs(toplevel, args, m_settings.timeout.value(),
ShellCommand::SshPasswordPrompt); VcsCommand::SshPasswordPrompt);
if (logResponse.result != CvsResponse::Ok) { if (logResponse.result != CvsResponse::Ok) {
*errorMessage = logResponse.message; *errorMessage = logResponse.message;
return false; return false;
@@ -1322,7 +1322,7 @@ bool CvsPluginPrivate::describe(const FilePath &toplevel, const QString &file, c
args << QLatin1String("log") << QLatin1String("-d") << (dateS + QLatin1Char('<') + nextDayS); args << QLatin1String("log") << QLatin1String("-d") << (dateS + QLatin1Char('<') + nextDayS);
const CvsResponse repoLogResponse = runCvs(toplevel, args, 10 * m_settings.timeout.value(), const CvsResponse repoLogResponse = runCvs(toplevel, args, 10 * m_settings.timeout.value(),
ShellCommand::SshPasswordPrompt); VcsCommand::SshPasswordPrompt);
if (repoLogResponse.result != CvsResponse::Ok) { if (repoLogResponse.result != CvsResponse::Ok) {
*errorMessage = repoLogResponse.message; *errorMessage = repoLogResponse.message;
return false; return false;
@@ -1359,7 +1359,7 @@ bool CvsPluginPrivate::describe(const FilePath &repositoryPath,
QStringList args(QLatin1String("log")); QStringList args(QLatin1String("log"));
args << (QLatin1String("-r") + it->revisions.front().revision) << it->file; args << (QLatin1String("-r") + it->revisions.front().revision) << it->file;
const CvsResponse logResponse = runCvs(repositoryPath, args, m_settings.timeout.value(), const CvsResponse logResponse = runCvs(repositoryPath, args, m_settings.timeout.value(),
ShellCommand::SshPasswordPrompt); VcsCommand::SshPasswordPrompt);
if (logResponse.result != CvsResponse::Ok) { if (logResponse.result != CvsResponse::Ok) {
*errorMessage = logResponse.message; *errorMessage = logResponse.message;
return false; return false;
@@ -1535,7 +1535,7 @@ bool CvsPluginPrivate::managesFile(const FilePath &workingDirectory, const QStri
QStringList args; QStringList args;
args << QLatin1String("status") << fileName; args << QLatin1String("status") << fileName;
const CvsResponse response = 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) if (response.result != CvsResponse::Ok)
return false; return false;
return !response.stdOut.contains(QLatin1String("Status: Unknown")); return !response.stdOut.contains(QLatin1String("Status: Unknown"));

View File

@@ -27,11 +27,11 @@
#include "gitclient.h" #include "gitclient.h"
#include "gitconstants.h" #include "gitconstants.h"
#include <vcsbase/vcscommand.h>
#include <vcsbase/vcsoutputwindow.h> #include <vcsbase/vcsoutputwindow.h>
#include <utils/filesystemwatcher.h> #include <utils/filesystemwatcher.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/shellcommand.h>
#include <utils/stringutils.h> #include <utils/stringutils.h>
#include <QDateTime> #include <QDateTime>
@@ -624,7 +624,7 @@ void BranchModel::removeTag(const QModelIndex &idx)
removeNode(idx); removeNode(idx);
} }
ShellCommand *BranchModel::checkoutBranch(const QModelIndex &idx) VcsCommand *BranchModel::checkoutBranch(const QModelIndex &idx)
{ {
QString branch = fullName(idx, !isLocal(idx)); QString branch = fullName(idx, !isLocal(idx));
if (branch.isEmpty()) if (branch.isEmpty())
@@ -690,7 +690,7 @@ QModelIndex BranchModel::addBranch(const QString &name, bool track, const QModel
} else { } else {
const QStringList arguments({"-n1", "--format=%H %ct"}); const QStringList arguments({"-n1", "--format=%H %ct"});
if (d->client->synchronousLog(d->workingDirectory, arguments, &output, &errorMessage, if (d->client->synchronousLog(d->workingDirectory, arguments, &output, &errorMessage,
ShellCommand::SuppressCommandLogging)) { VcsCommand::SuppressCommandLogging)) {
const QStringList values = output.split(' '); const QStringList values = output.split(' ');
startSha = values[0]; startSha = values[0];
branchDateTime = QDateTime::fromSecsSinceEpoch(values[1].toLongLong()); branchDateTime = QDateTime::fromSecsSinceEpoch(values[1].toLongLong());
@@ -908,9 +908,9 @@ void BranchModel::updateUpstreamStatus(BranchNode *node)
{ {
if (node->tracking.isEmpty()) if (node->tracking.isEmpty())
return; return;
ShellCommand *command = d->client->asyncUpstreamStatus( VcsCommand *command = d->client->asyncUpstreamStatus(
d->workingDirectory, node->fullRef(), node->tracking); 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()) if (text.isEmpty())
return; return;
const QStringList split = text.trimmed().split('\t'); const QStringList split = text.trimmed().split('\t');
@@ -930,7 +930,7 @@ QString BranchModel::toolTip(const QString &sha) const
QStringList arguments("-n1"); QStringList arguments("-n1");
arguments << sha; arguments << sha;
if (!d->client->synchronousLog(d->workingDirectory, arguments, &output, &errorMessage, if (!d->client->synchronousLog(d->workingDirectory, arguments, &output, &errorMessage,
ShellCommand::SuppressCommandLogging)) { VcsCommand::SuppressCommandLogging)) {
return errorMessage; return errorMessage;
} }
return output; return output;

View File

@@ -31,7 +31,7 @@
#include <QAbstractListModel> #include <QAbstractListModel>
#include <QVariant> #include <QVariant>
namespace Utils { class ShellCommand; } namespace VcsBase { class VcsCommand; }
namespace Git { namespace Git {
namespace Internal { namespace Internal {
@@ -80,7 +80,7 @@ public:
void removeBranch(const QModelIndex &idx); void removeBranch(const QModelIndex &idx);
void removeTag(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); bool branchIsMerged(const QModelIndex &idx);
QModelIndex addBranch(const QString &name, bool track, const QModelIndex &trackedBranch); QModelIndex addBranch(const QString &name, bool track, const QModelIndex &trackedBranch);
void setRemoteTracking(const QModelIndex &trackingIndex); void setRemoteTracking(const QModelIndex &trackingIndex);

View File

@@ -36,12 +36,14 @@
#include <coreplugin/actionmanager/command.h> #include <coreplugin/actionmanager/command.h>
#include <coreplugin/documentmanager.h> #include <coreplugin/documentmanager.h>
#include <coreplugin/inavigationwidgetfactory.h> #include <coreplugin/inavigationwidgetfactory.h>
#include <utils/elidinglabel.h> #include <utils/elidinglabel.h>
#include <utils/fancylineedit.h> #include <utils/fancylineedit.h>
#include <utils/navigationtreeview.h> #include <utils/navigationtreeview.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/shellcommand.h>
#include <utils/utilsicons.h> #include <utils/utilsicons.h>
#include <vcsbase/vcscommand.h>
#include <vcsbase/vcsoutputwindow.h> #include <vcsbase/vcsoutputwindow.h>
#include <QDir> #include <QDir>
@@ -57,6 +59,7 @@
using namespace Core; using namespace Core;
using namespace Utils; using namespace Utils;
using namespace VcsBase;
namespace Git { namespace Git {
namespace Internal { namespace Internal {
@@ -435,11 +438,11 @@ bool BranchView::checkout()
return false; return false;
} }
ShellCommand *command = m_model->checkoutBranch(selected); VcsCommand *command = m_model->checkoutBranch(selected);
const bool moveChanges = branchCheckoutDialog.moveLocalChangesToNextBranch(); const bool moveChanges = branchCheckoutDialog.moveLocalChangesToNextBranch();
const bool popStash = branchCheckoutDialog.popStashOfNextBranch(); const bool popStash = branchCheckoutDialog.popStashOfNextBranch();
if (command && (moveChanges || popStash)) { if (command && (moveChanges || popStash)) {
connect(command, &ShellCommand::finished, connect(command, &VcsCommand::finished,
this, [this, client, popMessageStart, moveChanges, popStash] { this, [this, client, popMessageStart, moveChanges, popStash] {
if (moveChanges) { if (moveChanges) {
client->endStashScope(m_repository); client->endStashScope(m_repository);

View File

@@ -32,9 +32,10 @@
#include <utils/pathchooser.h> #include <utils/pathchooser.h>
#include <utils/qtcprocess.h> #include <utils/qtcprocess.h>
#include <utils/shellcommand.h>
#include <utils/theme/theme.h> #include <utils/theme/theme.h>
#include <vcsbase/vcscommand.h>
#include <QCompleter> #include <QCompleter>
#include <QDir> #include <QDir>
#include <QFileDialog> #include <QFileDialog>
@@ -48,6 +49,7 @@
#include <QTimer> #include <QTimer>
using namespace Utils; using namespace Utils;
using namespace VcsBase;
namespace Git { namespace Git {
namespace Internal { namespace Internal {
@@ -194,9 +196,9 @@ void ChangeSelectionDialog::recalculateCompletion()
return; return;
GitClient *client = GitClient::instance(); GitClient *client = GitClient::instance();
ShellCommand *command = client->asyncForEachRefCmd(workingDir, {"--format=%(refname:short)"}); VcsCommand *command = client->asyncForEachRefCmd(workingDir, {"--format=%(refname:short)"});
connect(this, &QObject::destroyed, command, &ShellCommand::abort); connect(this, &QObject::destroyed, command, &VcsCommand::abort);
connect(command, &ShellCommand::stdOutText, [this](const QString &output) { connect(command, &VcsCommand::stdOutText, [this](const QString &output) {
m_changeModel->setStringList(output.split('\n')); m_changeModel->setStringList(output.split('\n'));
}); });
} }

View File

@@ -32,7 +32,8 @@
#include <utils/commandline.h> #include <utils/commandline.h>
#include <utils/hostosinfo.h> #include <utils/hostosinfo.h>
#include <utils/shellcommand.h>
#include <vcsbase/vcscommand.h>
#include <QFile> #include <QFile>
#include <QJsonDocument> #include <QJsonDocument>
@@ -41,8 +42,9 @@
#include <QRegularExpression> #include <QRegularExpression>
#include <QSettings> #include <QSettings>
using namespace Utils;
using namespace Git::Internal; using namespace Git::Internal;
using namespace Utils;
using namespace VcsBase;
namespace Gerrit { namespace Gerrit {
namespace Internal { namespace Internal {
@@ -243,7 +245,7 @@ int GerritServer::testConnection()
static GitClient *const client = GitClient::instance(); static GitClient *const client = GitClient::instance();
const QStringList arguments = curlArguments() << (url(RestUrl) + accountUrlC); const QStringList arguments = curlArguments() << (url(RestUrl) + accountUrlC);
const CommandResult result = client->vcsFullySynchronousExec({}, {curlBinary, arguments}, const CommandResult result = client->vcsFullySynchronousExec({}, {curlBinary, arguments},
ShellCommand::NoOutput); VcsCommand::NoOutput);
if (result.result() == ProcessResult::FinishedWithSuccess) { if (result.result() == ProcessResult::FinishedWithSuccess) {
QString output = result.cleanedStdOut(); QString output = result.cleanedStdOut();
// Gerrit returns an empty response for /p/qt-creator/a/accounts/self // 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 << p.portFlag << QString::number(port);
arguments << hostArgument() << "gerrit" << "version"; arguments << hostArgument() << "gerrit" << "version";
const CommandResult result = client->vcsFullySynchronousExec({}, {p.ssh, arguments}, const CommandResult result = client->vcsFullySynchronousExec({}, {p.ssh, arguments},
ShellCommand::NoOutput); VcsCommand::NoOutput);
QString stdOut = result.cleanedStdOut().trimmed(); QString stdOut = result.cleanedStdOut().trimmed();
stdOut.remove("gerrit version "); stdOut.remove("gerrit version ");
version = stdOut; version = stdOut;
@@ -352,7 +354,7 @@ bool GerritServer::resolveVersion(const GerritParameters &p, bool forceReload)
} else { } else {
const QStringList arguments = curlArguments() << (url(RestUrl) + versionUrlC); const QStringList arguments = curlArguments() << (url(RestUrl) + versionUrlC);
const CommandResult result = client->vcsFullySynchronousExec({}, {curlBinary, arguments}, 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 // REST endpoint for version is only available from 2.8 and up. Do not consider invalid
// if it fails. // if it fails.
if (result.result() == ProcessResult::FinishedWithSuccess) { if (result.result() == ProcessResult::FinishedWithSuccess) {

View File

@@ -49,7 +49,6 @@
#include <utils/mimeutils.h> #include <utils/mimeutils.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/qtcprocess.h> #include <utils/qtcprocess.h>
#include <utils/shellcommand.h>
#include <utils/stringutils.h> #include <utils/stringutils.h>
#include <utils/temporaryfile.h> #include <utils/temporaryfile.h>
#include <utils/theme/theme.h> #include <utils/theme/theme.h>
@@ -60,6 +59,7 @@
#include <vcsbase/vcsbaseeditorconfig.h> #include <vcsbase/vcsbaseeditorconfig.h>
#include <vcsbase/vcsbaseplugin.h> #include <vcsbase/vcsbaseplugin.h>
#include <vcsbase/vcsbasesubmiteditor.h> #include <vcsbase/vcsbasesubmiteditor.h>
#include <vcsbase/vcscommand.h>
#include <vcsbase/vcsoutputwindow.h> #include <vcsbase/vcsoutputwindow.h>
#include <diffeditor/descriptionwidgetwatcher.h> #include <diffeditor/descriptionwidgetwatcher.h>
@@ -116,12 +116,12 @@ static GitClient *m_instance = nullptr;
// Suppress git diff warnings about "LF will be replaced by CRLF..." on Windows. // Suppress git diff warnings about "LF will be replaced by CRLF..." on Windows.
static unsigned diffExecutionFlags() static unsigned diffExecutionFlags()
{ {
return HostOsInfo::isWindowsHost() ? unsigned(ShellCommand::SuppressStdErr) : 0u; return HostOsInfo::isWindowsHost() ? unsigned(VcsCommand::SuppressStdErr) : 0u;
} }
const unsigned silentFlags = unsigned(ShellCommand::SuppressCommandLogging const unsigned silentFlags = unsigned(VcsCommand::SuppressCommandLogging
| ShellCommand::SuppressStdErr | VcsCommand::SuppressStdErr
| ShellCommand::SuppressFailMessage); | VcsCommand::SuppressFailMessage);
static QString branchesDisplay(const QString &prefix, QStringList *branches, bool *first) static QString branchesDisplay(const QString &prefix, QStringList *branches, bool *first)
{ {
@@ -345,11 +345,11 @@ void GitBaseDiffEditorController::updateBranchList()
return; return;
const FilePath workingDirectory = baseDirectory(); const FilePath workingDirectory = baseDirectory();
ShellCommand *command = m_instance->vcsExec( VcsCommand *command = m_instance->vcsExec(
workingDirectory, workingDirectory,
{"branch", noColorOption, "-a", "--contains", revision}, nullptr, {"branch", noColorOption, "-a", "--contains", revision}, nullptr,
false, 0, workingDirectory.toString()); 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 remotePrefix = "remotes/";
const QString localPrefix = "<Local>"; const QString localPrefix = "<Local>";
const int prefixLength = remotePrefix.length(); const int prefixLength = remotePrefix.length();
@@ -484,7 +484,7 @@ private:
QString m_body; QString m_body;
QString m_precedes; QString m_precedes;
std::vector<QString> m_follows; std::vector<QString> m_follows;
QList<QPointer<ShellCommand>> m_commands; QList<QPointer<VcsCommand>> m_commands;
}; };
void ShowController::processCommandOutput(const QString &output) void ShowController::processCommandOutput(const QString &output)
@@ -562,7 +562,7 @@ void ShowController::updateDescription()
void ShowController::abortCommands() void ShowController::abortCommands()
{ {
for (QPointer<ShellCommand> command : m_commands) { for (QPointer<VcsCommand> command : m_commands) {
if (command) if (command)
command->abort(); command->abort();
} }
@@ -743,16 +743,16 @@ class ConflictHandler final : public QObject
{ {
Q_OBJECT Q_OBJECT
public: 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); auto handler = new ConflictHandler(command->defaultWorkingDirectory(), abortCommand);
handler->setParent(command); // delete when command goes out of scope handler->setParent(command); // delete when command goes out of scope
command->addFlags(ShellCommand::ExpectRepoChanges); command->addFlags(VcsCommand::ExpectRepoChanges);
connect(command, &ShellCommand::stdOutText, handler, &ConflictHandler::readStdOut); connect(command, &VcsCommand::stdOutText, handler, &ConflictHandler::readStdOut);
connect(command, &ShellCommand::stdErrText, handler, &ConflictHandler::readStdErr); 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 FilePath &workingDirectory,
const QString &abortCommand = QString()) const QString &abortCommand = QString())
{ {
@@ -811,7 +811,7 @@ private:
class GitProgressParser : public ProgressParser class GitProgressParser : public ProgressParser
{ {
public: public:
static void attachToCommand(ShellCommand *command) static void attachToCommand(VcsCommand *command)
{ {
command->setProgressParser(new GitProgressParser); 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 bool GitClient::managesFile(const FilePath &workingDirectory, const QString &fileName) const
{ {
const CommandResult result = vcsFullySynchronousExec(workingDirectory, const CommandResult result = vcsFullySynchronousExec(workingDirectory,
{"ls-files", "--error-unmatch", fileName}, ShellCommand::NoOutput); {"ls-files", "--error-unmatch", fileName}, VcsCommand::NoOutput);
return result.result() == ProcessResult::FinishedWithSuccess; return result.result() == ProcessResult::FinishedWithSuccess;
} }
@@ -937,7 +937,7 @@ FilePaths GitClient::unmanagedFiles(const FilePaths &filePaths) const
QStringList args({"ls-files", "-z"}); QStringList args({"ls-files", "-z"});
const QDir wd(it.key().toString()); const QDir wd(it.key().toString());
args << transform(it.value(), [&wd](const QString &fp) { return wd.relativeFilePath(fp); }); 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) if (result.result() != ProcessResult::FinishedWithSuccess)
return filePaths; return filePaths;
const QStringList managedFilePaths const QStringList managedFilePaths
@@ -1147,8 +1147,8 @@ void GitClient::merge(const FilePath &workingDirectory, const QStringList &unmer
void GitClient::status(const FilePath &workingDirectory) const void GitClient::status(const FilePath &workingDirectory) const
{ {
VcsOutputWindow::setRepository(workingDirectory.toString()); VcsOutputWindow::setRepository(workingDirectory.toString());
ShellCommand *command = vcsExec(workingDirectory, {"status", "-u"}, nullptr, true); VcsCommand *command = vcsExec(workingDirectory, {"status", "-u"}, nullptr, true);
connect(command, &ShellCommand::finished, VcsOutputWindow::instance(), connect(command, &VcsCommand::finished, VcsOutputWindow::instance(),
&VcsOutputWindow::clearRepository, Qt::QueuedConnection); &VcsOutputWindow::clearRepository, Qt::QueuedConnection);
} }
@@ -1383,16 +1383,16 @@ VcsBaseEditorWidget *GitClient::annotate(
return editor; return editor;
} }
ShellCommand *GitClient::checkout(const FilePath &workingDirectory, const QString &ref, VcsCommand *GitClient::checkout(const FilePath &workingDirectory, const QString &ref,
StashMode stashMode) StashMode stashMode)
{ {
if (stashMode == StashMode::TryStash && !beginStashScope(workingDirectory, "Checkout")) if (stashMode == StashMode::TryStash && !beginStashScope(workingDirectory, "Checkout"))
return nullptr; return nullptr;
QStringList arguments = setupCheckoutArguments(workingDirectory, ref); QStringList arguments = setupCheckoutArguments(workingDirectory, ref);
ShellCommand *command = vcsExec( VcsCommand *command = vcsExec(
workingDirectory, arguments, nullptr, true, workingDirectory, arguments, nullptr, true,
ShellCommand::ExpectRepoChanges | ShellCommand::ShowSuccessMessage); VcsCommand::ExpectRepoChanges | VcsCommand::ShowSuccessMessage);
connect(command, &ShellCommand::finished, connect(command, &VcsCommand::finished,
this, [this, workingDirectory, stashMode](bool success) { this, [this, workingDirectory, stashMode](bool success) {
if (stashMode == StashMode::TryStash) if (stashMode == StashMode::TryStash)
endStashScope(workingDirectory); endStashScope(workingDirectory);
@@ -1481,7 +1481,7 @@ void GitClient::reset(const FilePath &workingDirectory, const QString &argument,
if (!commit.isEmpty()) if (!commit.isEmpty())
arguments << commit; arguments << commit;
unsigned flags = ShellCommand::ShowSuccessMessage; unsigned flags = VcsCommand::ShowSuccessMessage;
if (argument == "--hard") { if (argument == "--hard") {
if (gitStatus(workingDirectory, StatusMode(NoUntracked | NoSubmodules)) != StatusUnchanged) { if (gitStatus(workingDirectory, StatusMode(NoUntracked | NoSubmodules)) != StatusUnchanged) {
if (QMessageBox::question( if (QMessageBox::question(
@@ -1492,7 +1492,7 @@ void GitClient::reset(const FilePath &workingDirectory, const QString &argument,
return; return;
} }
} }
flags |= ShellCommand::ExpectRepoChanges; flags |= VcsCommand::ExpectRepoChanges;
} }
vcsExec(workingDirectory, arguments, nullptr, true, flags); vcsExec(workingDirectory, arguments, nullptr, true, flags);
} }
@@ -1501,10 +1501,10 @@ void GitClient::removeStaleRemoteBranches(const FilePath &workingDirectory, cons
{ {
const QStringList arguments = {"remote", "prune", remote}; const QStringList arguments = {"remote", "prune", remote};
ShellCommand *command = vcsExec(workingDirectory, arguments, nullptr, true, VcsCommand *command = vcsExec(workingDirectory, arguments, nullptr, true,
ShellCommand::ShowSuccessMessage); VcsCommand::ShowSuccessMessage);
connect(command, &ShellCommand::finished, this, [workingDirectory](bool success) { connect(command, &VcsCommand::finished, this, [workingDirectory](bool success) {
if (success) if (success)
GitPlugin::updateBranches(workingDirectory); GitPlugin::updateBranches(workingDirectory);
}); });
@@ -1513,7 +1513,7 @@ void GitClient::removeStaleRemoteBranches(const FilePath &workingDirectory, cons
void GitClient::recoverDeletedFiles(const FilePath &workingDirectory) void GitClient::recoverDeletedFiles(const FilePath &workingDirectory)
{ {
const CommandResult result = vcsFullySynchronousExec(workingDirectory, {"ls-files", "--deleted"}, const CommandResult result = vcsFullySynchronousExec(workingDirectory, {"ls-files", "--deleted"},
ShellCommand::SuppressCommandLogging); VcsCommand::SuppressCommandLogging);
if (result.result() == ProcessResult::FinishedWithSuccess) { if (result.result() == ProcessResult::FinishedWithSuccess) {
const QString stdOut = result.cleanedStdOut().trimmed(); const QString stdOut = result.cleanedStdOut().trimmed();
if (stdOut.isEmpty()) { if (stdOut.isEmpty()) {
@@ -1639,7 +1639,7 @@ bool GitClient::synchronousCheckoutFiles(const FilePath &workingDirectory, QStri
arguments << revision; arguments << revision;
arguments << "--" << files; arguments << "--" << files;
const CommandResult result = vcsFullySynchronousExec(workingDirectory, arguments, const CommandResult result = vcsFullySynchronousExec(workingDirectory, arguments,
ShellCommand::ExpectRepoChanges); VcsCommand::ExpectRepoChanges);
if (result.result() == ProcessResult::FinishedWithSuccess) if (result.result() == ProcessResult::FinishedWithSuccess)
return true; return true;
@@ -1827,7 +1827,7 @@ QString GitClient::synchronousTopic(const FilePath &workingDirectory) const
// No tag or remote branch - try git describe // No tag or remote branch - try git describe
const CommandResult result = vcsFullySynchronousExec(workingDirectory, QStringList{"describe"}, const CommandResult result = vcsFullySynchronousExec(workingDirectory, QStringList{"describe"},
ShellCommand::NoOutput); VcsCommand::NoOutput);
if (result.result() == ProcessResult::FinishedWithSuccess) { if (result.result() == ProcessResult::FinishedWithSuccess) {
const QString stdOut = result.cleanedStdOut().trimmed(); const QString stdOut = result.cleanedStdOut().trimmed();
if (!stdOut.isEmpty()) if (!stdOut.isEmpty())
@@ -1961,9 +1961,9 @@ bool GitClient::executeSynchronousStash(const FilePath &workingDirectory,
arguments << "--keep-index"; arguments << "--keep-index";
if (!message.isEmpty()) if (!message.isEmpty())
arguments << message; arguments << message;
const unsigned flags = ShellCommand::ShowStdOut const unsigned flags = VcsCommand::ShowStdOut
| ShellCommand::ExpectRepoChanges | VcsCommand::ExpectRepoChanges
| ShellCommand::ShowSuccessMessage; | VcsCommand::ShowSuccessMessage;
const CommandResult result = vcsSynchronousExec(workingDirectory, arguments, flags); const CommandResult result = vcsSynchronousExec(workingDirectory, arguments, flags);
if (result.result() == ProcessResult::FinishedWithSuccess) if (result.result() == ProcessResult::FinishedWithSuccess)
return true; return true;
@@ -2033,7 +2033,7 @@ bool GitClient::synchronousForEachRefCmd(const FilePath &workingDirectory, QStri
return false; 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"); args.push_front("for-each-ref");
return vcsExec(workingDirectory, args, nullptr, false, silentFlags); 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 QStringList arguments = {"clean", "--dry-run", flag};
const CommandResult result = vcsFullySynchronousExec(directory, arguments, const CommandResult result = vcsFullySynchronousExec(directory, arguments,
ShellCommand::ForceCLocale); VcsCommand::ForceCLocale);
if (result.result() != ProcessResult::FinishedWithSuccess) { if (result.result() != ProcessResult::FinishedWithSuccess) {
msgCannotRun(arguments, directory, result.cleanedStdErr(), errorMessage); msgCannotRun(arguments, directory, result.cleanedStdErr(), errorMessage);
return false; return false;
@@ -2339,9 +2339,9 @@ void GitClient::updateSubmodulesIfNeeded(const FilePath &workingDirectory, bool
} }
} }
ShellCommand *cmd = vcsExec(workingDirectory, {"submodule", "update"}, nullptr, true, VcsCommand *cmd = vcsExec(workingDirectory, {"submodule", "update"}, nullptr, true,
ShellCommand::ExpectRepoChanges); VcsCommand::ExpectRepoChanges);
connect(cmd, &ShellCommand::finished, this, &GitClient::finishSubmoduleUpdate); connect(cmd, &VcsCommand::finished, this, &GitClient::finishSubmoduleUpdate);
} }
void GitClient::finishSubmoduleUpdate() void GitClient::finishSubmoduleUpdate()
@@ -2506,9 +2506,9 @@ void GitClient::continuePreviousGitCommand(const FilePath &workingDirectory,
QStringList GitClient::synchronousRepositoryBranches(const QString &repositoryURL, QStringList GitClient::synchronousRepositoryBranches(const QString &repositoryURL,
const FilePath &workingDirectory) const const FilePath &workingDirectory) const
{ {
const unsigned flags = ShellCommand::SshPasswordPrompt const unsigned flags = VcsCommand::SshPasswordPrompt
| ShellCommand::SuppressStdErr | VcsCommand::SuppressStdErr
| ShellCommand::SuppressFailMessage; | VcsCommand::SuppressFailMessage;
const CommandResult result = vcsSynchronousExec(workingDirectory, const CommandResult result = vcsSynchronousExec(workingDirectory,
{"ls-remote", repositoryURL, HEAD, "refs/heads/*"}, flags); {"ls-remote", repositoryURL, HEAD, "refs/heads/*"}, flags);
QStringList branches; QStringList branches;
@@ -2783,7 +2783,7 @@ bool GitClient::getCommitData(const FilePath &workingDirectory,
QString output; QString output;
if (commitData.commitType == FixupCommit) { if (commitData.commitType == FixupCommit) {
synchronousLog(repoDirectory, {HEAD, "--not", "--remotes", "-n1"}, &output, errorMessage, synchronousLog(repoDirectory, {HEAD, "--not", "--remotes", "-n1"}, &output, errorMessage,
ShellCommand::SuppressCommandLogging); VcsCommand::SuppressCommandLogging);
if (output.isEmpty()) { if (output.isEmpty()) {
*errorMessage = msgNoCommits(false); *errorMessage = msgNoCommits(false);
return false; return false;
@@ -2992,7 +2992,7 @@ bool GitClient::addAndCommit(const FilePath &repositoryDirectory,
} }
const CommandResult result = vcsSynchronousExec(repositoryDirectory, arguments, const CommandResult result = vcsSynchronousExec(repositoryDirectory, arguments,
ShellCommand::NoFullySync); VcsCommand::NoFullySync);
if (result.result() == ProcessResult::FinishedWithSuccess) { if (result.result() == ProcessResult::FinishedWithSuccess) {
VcsOutputWindow::appendMessage(msgCommitted(amendSHA1, commitCount)); VcsOutputWindow::appendMessage(msgCommitted(amendSHA1, commitCount));
GitPlugin::updateCurrentBranch(); GitPlugin::updateCurrentBranch();
@@ -3115,9 +3115,9 @@ void GitClient::revertFiles(const QStringList &files, bool revertStaging)
void GitClient::fetch(const FilePath &workingDirectory, const QString &remote) void GitClient::fetch(const FilePath &workingDirectory, const QString &remote)
{ {
QStringList const arguments = {"fetch", (remote.isEmpty() ? "--all" : remote)}; QStringList const arguments = {"fetch", (remote.isEmpty() ? "--all" : remote)};
ShellCommand *command = vcsExec(workingDirectory, arguments, nullptr, true, VcsCommand *command = vcsExec(workingDirectory, arguments, nullptr, true,
ShellCommand::ShowSuccessMessage); VcsCommand::ShowSuccessMessage);
connect(command, &ShellCommand::finished, this, [workingDirectory](bool success) { connect(command, &VcsCommand::finished, this, [workingDirectory](bool success) {
if (success) if (success)
GitPlugin::updateBranches(workingDirectory); GitPlugin::updateBranches(workingDirectory);
}); });
@@ -3128,10 +3128,10 @@ bool GitClient::executeAndHandleConflicts(const FilePath &workingDirectory,
const QString &abortCommand) const const QString &abortCommand) const
{ {
// Disable UNIX terminals to suppress SSH prompting. // Disable UNIX terminals to suppress SSH prompting.
const unsigned flags = ShellCommand::SshPasswordPrompt const unsigned flags = VcsCommand::SshPasswordPrompt
| ShellCommand::ShowStdOut | VcsCommand::ShowStdOut
| ShellCommand::ExpectRepoChanges | VcsCommand::ExpectRepoChanges
| ShellCommand::ShowSuccessMessage; | VcsCommand::ShowSuccessMessage;
const CommandResult result = vcsSynchronousExec(workingDirectory, arguments, flags); const CommandResult result = vcsSynchronousExec(workingDirectory, arguments, flags);
// Notify about changed files or abort the rebase. // Notify about changed files or abort the rebase.
ConflictHandler::handleResponse(result, workingDirectory, abortCommand); ConflictHandler::handleResponse(result, workingDirectory, abortCommand);
@@ -3149,8 +3149,8 @@ void GitClient::pull(const FilePath &workingDirectory, bool rebase)
abortCommand = "merge"; abortCommand = "merge";
} }
ShellCommand *command = vcsExecAbortable(workingDirectory, arguments, rebase, abortCommand); VcsCommand *command = vcsExecAbortable(workingDirectory, arguments, rebase, abortCommand);
connect(command, &ShellCommand::finished, this, [this, workingDirectory](bool success) { connect(command, &VcsCommand::finished, this, [this, workingDirectory](bool success) {
if (success) if (success)
updateSubmodulesIfNeeded(workingDirectory, true); updateSubmodulesIfNeeded(workingDirectory, true);
}, Qt::QueuedConnection); }, Qt::QueuedConnection);
@@ -3167,7 +3167,7 @@ void GitClient::synchronousAbortCommand(const FilePath &workingDir, const QStrin
} }
const CommandResult result = vcsFullySynchronousExec(workingDir, {abortCommand, "--abort"}, const CommandResult result = vcsFullySynchronousExec(workingDir, {abortCommand, "--abort"},
ShellCommand::ExpectRepoChanges | ShellCommand::ShowSuccessMessage); VcsCommand::ExpectRepoChanges | VcsCommand::ShowSuccessMessage);
VcsOutputWindow::append(result.cleanedStdOut()); VcsOutputWindow::append(result.cleanedStdOut());
} }
@@ -3196,9 +3196,9 @@ bool GitClient::synchronousSetTrackingBranch(const FilePath &workingDirectory,
return result.result() == ProcessResult::FinishedWithSuccess; return result.result() == ProcessResult::FinishedWithSuccess;
} }
ShellCommand *GitClient::asyncUpstreamStatus(const FilePath &workingDirectory, VcsCommand *GitClient::asyncUpstreamStatus(const FilePath &workingDirectory,
const QString &branch, const QString &branch,
const QString &upstream) const QString &upstream)
{ {
const QStringList args {"rev-list", noColorOption, "--left-right", "--count", const QStringList args {"rev-list", noColorOption, "--left-right", "--count",
branch + "..." + upstream}; branch + "..." + upstream};
@@ -3261,9 +3261,9 @@ void GitClient::addFuture(const QFuture<void> &future)
void GitClient::synchronousSubversionFetch(const FilePath &workingDirectory) const void GitClient::synchronousSubversionFetch(const FilePath &workingDirectory) const
{ {
// Disable UNIX terminals to suppress SSH prompting. // Disable UNIX terminals to suppress SSH prompting.
const unsigned flags = ShellCommand::SshPasswordPrompt const unsigned flags = VcsCommand::SshPasswordPrompt
| ShellCommand::ShowStdOut | VcsCommand::ShowStdOut
| ShellCommand::ShowSuccessMessage; | VcsCommand::ShowSuccessMessage;
vcsSynchronousExec(workingDirectory, {"svn", "fetch"}, flags); vcsSynchronousExec(workingDirectory, {"svn", "fetch"}, flags);
} }
@@ -3286,15 +3286,14 @@ void GitClient::subversionLog(const FilePath &workingDirectory) const
void GitClient::subversionDeltaCommit(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) void GitClient::push(const FilePath &workingDirectory, const QStringList &pushArgs)
{ {
ShellCommand *command = vcsExec( VcsCommand *command = vcsExec(workingDirectory, QStringList({"push"}) + pushArgs, nullptr, true,
workingDirectory, QStringList({"push"}) + pushArgs, nullptr, true, VcsCommand::ShowSuccessMessage);
ShellCommand::ShowSuccessMessage); connect(command, &VcsCommand::stdErrText, this, [this, command](const QString &text) {
connect(command, &ShellCommand::stdErrText, this, [this, command](const QString &text) {
if (text.contains("non-fast-forward")) if (text.contains("non-fast-forward"))
command->setCookie(NonFastForward); command->setCookie(NonFastForward);
else if (text.contains("has no upstream branch")) 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) { this, [this, command, workingDirectory, pushArgs](bool success) {
if (!success) { if (!success) {
switch (static_cast<PushFailure>(command->cookie().toInt())) { switch (static_cast<PushFailure>(command->cookie().toInt())) {
@@ -3331,10 +3330,10 @@ void GitClient::push(const FilePath &workingDirectory, const QStringList &pushAr
.arg(QString::number(warnColor.rgba(), 16)), .arg(QString::number(warnColor.rgba(), 16)),
QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes | QMessageBox::No,
QMessageBox::No) == QMessageBox::Yes) { QMessageBox::No) == QMessageBox::Yes) {
ShellCommand *rePushCommand = vcsExec(workingDirectory, VcsCommand *rePushCommand = vcsExec(workingDirectory,
QStringList({"push", "--force-with-lease"}) + pushArgs, QStringList({"push", "--force-with-lease"}) + pushArgs,
nullptr, true, ShellCommand::ShowSuccessMessage); nullptr, true, VcsCommand::ShowSuccessMessage);
connect(rePushCommand, &ShellCommand::finished, this, [](bool success) { connect(rePushCommand, &VcsCommand::finished, this, [](bool success) {
if (success) if (success)
GitPlugin::updateCurrentBranch(); GitPlugin::updateCurrentBranch();
}); });
@@ -3354,10 +3353,10 @@ void GitClient::push(const FilePath &workingDirectory, const QStringList &pushAr
const QStringList fallbackCommandParts = const QStringList fallbackCommandParts =
m_pushFallbackCommand.split(' ', Qt::SkipEmptyParts); m_pushFallbackCommand.split(' ', Qt::SkipEmptyParts);
ShellCommand *rePushCommand = vcsExec(workingDirectory, VcsCommand *rePushCommand = vcsExec(workingDirectory,
fallbackCommandParts.mid(1), nullptr, true, fallbackCommandParts.mid(1), nullptr, true,
ShellCommand::ShowSuccessMessage); VcsCommand::ShowSuccessMessage);
connect(rePushCommand, &ShellCommand::finished, this, connect(rePushCommand, &VcsCommand::finished, this,
[workingDirectory](bool success) { [workingDirectory](bool success) {
if (success) if (success)
GitPlugin::updateBranches(workingDirectory); 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. // Executes a command asynchronously. Work tree is expected to be clean.
// Stashing is handled prior to this call. // Stashing is handled prior to this call.
ShellCommand *GitClient::vcsExecAbortable(const FilePath &workingDirectory, VcsCommand *GitClient::vcsExecAbortable(const FilePath &workingDirectory,
const QStringList &arguments, const QStringList &arguments,
bool isRebase, bool isRebase,
QString abortCommand) QString abortCommand)
{ {
QTC_ASSERT(!arguments.isEmpty(), return nullptr); QTC_ASSERT(!arguments.isEmpty(), return nullptr);
if (abortCommand.isEmpty()) if (abortCommand.isEmpty())
abortCommand = arguments.at(0); abortCommand = arguments.at(0);
ShellCommand *command = createCommand(workingDirectory, nullptr, VcsWindowOutputBind); VcsCommand *command = createCommand(workingDirectory, nullptr, VcsWindowOutputBind);
command->setCookie(workingDirectory.toString()); command->setCookie(workingDirectory.toString());
command->addFlags(ShellCommand::SshPasswordPrompt command->addFlags(VcsCommand::SshPasswordPrompt
| ShellCommand::ShowStdOut | VcsCommand::ShowStdOut
| ShellCommand::ShowSuccessMessage); | VcsCommand::ShowSuccessMessage);
// For rebase, Git might request an editor (which means the process keeps running until the // For rebase, Git might request an editor (which means the process keeps running until the
// user closes it), so run without timeout. // user closes it), so run without timeout.
command->addJob({vcsBinary(), arguments}, isRebase ? 0 : command->defaultTimeoutS()); 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"}; QStringList arguments = {"stash", "pop"};
if (!stash.isEmpty()) if (!stash.isEmpty())
arguments << stash; arguments << stash;
ShellCommand *cmd = vcsExec(workingDirectory, arguments, nullptr, true, VcsCommand *cmd = vcsExec(workingDirectory, arguments, nullptr, true,
ShellCommand::ExpectRepoChanges); VcsCommand::ExpectRepoChanges);
ConflictHandler::attachToCommand(cmd); ConflictHandler::attachToCommand(cmd);
} }
@@ -3535,7 +3534,7 @@ bool GitClient::synchronousStashList(const FilePath &workingDirectory, QList<Sta
const QStringList arguments = {"stash", "list", noColorOption}; const QStringList arguments = {"stash", "list", noColorOption};
const CommandResult result = vcsFullySynchronousExec(workingDirectory, arguments, const CommandResult result = vcsFullySynchronousExec(workingDirectory, arguments,
ShellCommand::ForceCLocale); VcsCommand::ForceCLocale);
if (result.result() != ProcessResult::FinishedWithSuccess) { if (result.result() != ProcessResult::FinishedWithSuccess) {
msgCannotRun(arguments, workingDirectory, result.cleanedStdErr(), errorMessage); msgCannotRun(arguments, workingDirectory, result.cleanedStdErr(), errorMessage);
return false; return false;
@@ -3763,7 +3762,7 @@ QString GitClient::suggestedLocalBranchName(
} else { } else {
QString subject; QString subject;
instance()->synchronousLog(workingDirectory, {"-n", "1", "--format=%s", target}, instance()->synchronousLog(workingDirectory, {"-n", "1", "--format=%s", target},
&subject, nullptr, ShellCommand::NoOutput); &subject, nullptr, VcsCommand::NoOutput);
initialName = subject.trimmed(); initialName = subject.trimmed();
} }
QString suggestedName = initialName; QString suggestedName = initialName;

View File

@@ -53,11 +53,10 @@ class ChunkSelection;
class DiffEditorController; class DiffEditorController;
} }
namespace Utils { class ShellCommand; }
namespace VcsBase { namespace VcsBase {
class SubmitFileModel; class SubmitFileModel;
class VcsBaseEditorWidget; class VcsBaseEditorWidget;
class VcsCommand;
} }
namespace Git { namespace Git {
@@ -148,7 +147,7 @@ public:
Utils::FilePath vcsBinary() const override; Utils::FilePath vcsBinary() const override;
QFuture<unsigned> gitVersion() const; QFuture<unsigned> gitVersion() const;
Utils::ShellCommand *vcsExecAbortable(const Utils::FilePath &workingDirectory, VcsBase::VcsCommand *vcsExecAbortable(const Utils::FilePath &workingDirectory,
const QStringList &arguments, const QStringList &arguments,
bool isRebase = false, bool isRebase = false,
QString abortCommand = {}); QString abortCommand = {});
@@ -208,7 +207,7 @@ public:
QString revision = {}, QString *errorMessage = nullptr, QString revision = {}, QString *errorMessage = nullptr,
bool revertStaging = true); bool revertStaging = true);
enum class StashMode { NoStash, TryStash }; 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); StashMode stashMode = StashMode::TryStash);
QStringList setupCheckoutArguments(const Utils::FilePath &workingDirectory, const QString &ref); QStringList setupCheckoutArguments(const Utils::FilePath &workingDirectory, const QString &ref);
@@ -237,7 +236,7 @@ public:
QString *output, QString *errorMessage) const; QString *output, QString *errorMessage) const;
bool synchronousForEachRefCmd(const Utils::FilePath &workingDirectory, QStringList args, bool synchronousForEachRefCmd(const Utils::FilePath &workingDirectory, QStringList args,
QString *output, QString *errorMessage = nullptr) const; 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, bool synchronousRemoteCmd(const Utils::FilePath &workingDirectory, QStringList remoteArgs,
QString *output = nullptr, QString *errorMessage = nullptr, QString *output = nullptr, QString *errorMessage = nullptr,
bool silent = false) const; bool silent = false) const;
@@ -360,7 +359,7 @@ public:
void show(const QString &source, const QString &id, const QString &name = {}); void show(const QString &source, const QString &id, const QString &name = {});
void archive(const Utils::FilePath &workingDirectory, QString commit); 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); const QString &branch, const QString &upstream);
enum class BranchTargetType { Remote, Commit }; enum class BranchTargetType { Remote, Commit };
@@ -396,7 +395,7 @@ private:
bool *isDirectory, bool *isDirectory,
QString *errorMessage, QString *errorMessage,
bool revertStaging); 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, bool executeAndHandleConflicts(const Utils::FilePath &workingDirectory, const QStringList &arguments,
const QString &abortCommand = {}) const; const QString &abortCommand = {}) const;
void tryLaunchingGitK(const Utils::Environment &env, void tryLaunchingGitK(const Utils::Environment &env,

View File

@@ -29,8 +29,11 @@
#include <coreplugin/editormanager/editormanager.h> #include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/progressmanager/progressmanager.h> #include <coreplugin/progressmanager/progressmanager.h>
#include <coreplugin/vcsmanager.h> #include <coreplugin/vcsmanager.h>
#include <texteditor/findinfiles.h> #include <texteditor/findinfiles.h>
#include <vcsbase/vcsbaseconstants.h> #include <vcsbase/vcsbaseconstants.h>
#include <vcsbase/vcscommand.h>
#include <utils/algorithm.h> #include <utils/algorithm.h>
#include <utils/commandline.h> #include <utils/commandline.h>
@@ -39,7 +42,6 @@
#include <utils/fileutils.h> #include <utils/fileutils.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/runextensions.h> #include <utils/runextensions.h>
#include <utils/shellcommand.h>
#include <utils/textfileformat.h> #include <utils/textfileformat.h>
#include <QCheckBox> #include <QCheckBox>
@@ -64,6 +66,7 @@ public:
using namespace Core; using namespace Core;
using namespace Utils; using namespace Utils;
using namespace VcsBase;
namespace { namespace {
@@ -187,16 +190,16 @@ public:
return QString(":!" + filter); return QString(":!" + filter);
}); });
arguments << "--" << filterArgs << exclusionArgs; arguments << "--" << filterArgs << exclusionArgs;
m_command->addFlags(ShellCommand::SilentOutput | ShellCommand::SuppressFailMessage); m_command->addFlags(VcsCommand::SilentOutput | VcsCommand::SuppressFailMessage);
m_command->setProgressiveOutput(true); m_command->setProgressiveOutput(true);
QFutureWatcher<FileSearchResultList> watcher; QFutureWatcher<FileSearchResultList> watcher;
QObject::connect(&watcher, QObject::connect(&watcher,
&QFutureWatcher<FileSearchResultList>::canceled, &QFutureWatcher<FileSearchResultList>::canceled,
m_command.get(), m_command.get(),
&ShellCommand::cancel); &VcsCommand::cancel);
watcher.setFuture(fi.future()); watcher.setFuture(fi.future());
QObject::connect(m_command.get(), QObject::connect(m_command.get(),
&ShellCommand::stdOutText, &VcsCommand::stdOutText,
[this, &fi](const QString &text) { read(fi, text); }); [this, &fi](const QString &text) { read(fi, text); });
const CommandResult result = m_command->runCommand({m_vcsBinary, arguments}, {}, 0); const CommandResult result = m_command->runCommand({m_vcsBinary, arguments}, {}, 0);
switch (result.result()) { switch (result.result()) {
@@ -218,7 +221,7 @@ private:
FilePath m_directory; FilePath m_directory;
QString m_ref; QString m_ref;
TextEditor::FileFindParameters m_parameters; TextEditor::FileFindParameters m_parameters;
std::unique_ptr<ShellCommand> m_command; std::unique_ptr<VcsCommand> m_command;
}; };
} // namespace } // namespace

View File

@@ -66,18 +66,18 @@
#include <utils/pathchooser.h> #include <utils/pathchooser.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/runextensions.h> #include <utils/runextensions.h>
#include <utils/shellcommand.h>
#include <utils/stringutils.h> #include <utils/stringutils.h>
#include <utils/utilsicons.h> #include <utils/utilsicons.h>
#include <vcsbase/basevcseditorfactory.h> #include <vcsbase/basevcseditorfactory.h>
#include <vcsbase/submitfilemodel.h>
#include <vcsbase/vcsbaseeditor.h>
#include <vcsbase/vcsbaseconstants.h>
#include <vcsbase/basevcssubmiteditorfactory.h> #include <vcsbase/basevcssubmiteditorfactory.h>
#include <vcsbase/vcsoutputwindow.h>
#include <vcsbase/cleandialog.h> #include <vcsbase/cleandialog.h>
#include <vcsbase/submitfilemodel.h>
#include <vcsbase/vcsbaseconstants.h>
#include <vcsbase/vcsbaseeditor.h>
#include <vcsbase/vcsbaseplugin.h> #include <vcsbase/vcsbaseplugin.h>
#include <vcsbase/vcscommand.h>
#include <vcsbase/vcsoutputwindow.h>
#include <QDebug> #include <QDebug>
#include <QDir> #include <QDir>
@@ -255,10 +255,10 @@ public:
void vcsDescribe(const FilePath &source, const QString &id) final { m_gitClient.show(source.toString(), id); }; void vcsDescribe(const FilePath &source, const QString &id) final { m_gitClient.show(source.toString(), id); };
QString vcsTopic(const FilePath &directory) final; QString vcsTopic(const FilePath &directory) final;
ShellCommand *createInitialCheckoutCommand(const QString &url, VcsCommand *createInitialCheckoutCommand(const QString &url,
const Utils::FilePath &baseDirectory, const Utils::FilePath &baseDirectory,
const QString &localName, const QString &localName,
const QStringList &extraArgs) final; const QStringList &extraArgs) final;
void fillLinkContextMenu(QMenu *menu, void fillLinkContextMenu(QMenu *menu,
const FilePath &workingDirectory, const FilePath &workingDirectory,
@@ -1880,16 +1880,16 @@ QString GitPluginPrivate::vcsTopic(const FilePath &directory)
return topic; return topic;
} }
ShellCommand *GitPluginPrivate::createInitialCheckoutCommand(const QString &url, VcsCommand *GitPluginPrivate::createInitialCheckoutCommand(const QString &url,
const Utils::FilePath &baseDirectory, const Utils::FilePath &baseDirectory,
const QString &localName, const QString &localName,
const QStringList &extraArgs) const QStringList &extraArgs)
{ {
QStringList args = {"clone", "--progress"}; QStringList args = {"clone", "--progress"};
args << extraArgs << url << localName; args << extraArgs << url << localName;
auto command = VcsBaseClient::createVcsCommand(baseDirectory, m_gitClient.processEnvironment()); auto command = VcsBaseClient::createVcsCommand(baseDirectory, m_gitClient.processEnvironment());
command->addFlags(ShellCommand::SuppressStdErr); command->addFlags(VcsCommand::SuppressStdErr);
command->addJob({m_gitClient.vcsBinary(), args}, -1); command->addJob({m_gitClient.vcsBinary(), args}, -1);
return command; return command;
} }

View File

@@ -26,10 +26,10 @@
#include "logchangedialog.h" #include "logchangedialog.h"
#include "gitclient.h" #include "gitclient.h"
#include <vcsbase/vcscommand.h>
#include <vcsbase/vcsoutputwindow.h> #include <vcsbase/vcsoutputwindow.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/shellcommand.h>
#include <QComboBox> #include <QComboBox>
#include <QDialogButtonBox> #include <QDialogButtonBox>
@@ -67,9 +67,8 @@ public:
const auto it = m_descriptions.constFind(revision); const auto it = m_descriptions.constFind(revision);
if (it != m_descriptions.constEnd()) if (it != m_descriptions.constEnd())
return *it; return *it;
const QString desc = QString::fromUtf8( const QString desc = QString::fromUtf8(GitClient::instance()->synchronousShow(
GitClient::instance()->synchronousShow( m_workingDirectory, revision, VcsCommand::NoOutput));
m_workingDirectory, revision, ShellCommand::NoOutput));
m_descriptions[revision] = desc; m_descriptions[revision] = desc;
return desc; return desc;
} }
@@ -192,7 +191,7 @@ bool LogChangeWidget::populateLog(const FilePath &repository, const QString &com
arguments << "--"; arguments << "--";
QString output; QString output;
if (!GitClient::instance()->synchronousLog( if (!GitClient::instance()->synchronousLog(
repository, arguments, &output, nullptr, ShellCommand::NoOutput)) { repository, arguments, &output, nullptr, VcsCommand::NoOutput)) {
return false; return false;
} }
const QStringList lines = output.split('\n'); const QStringList lines = output.split('\n');

View File

@@ -30,9 +30,12 @@
#include <coreplugin/documentmanager.h> #include <coreplugin/documentmanager.h>
#include <coreplugin/vcsmanager.h> #include <coreplugin/vcsmanager.h>
#include <git/gitclient.h> #include <git/gitclient.h>
#include <projectexplorer/projectexplorer.h> #include <projectexplorer/projectexplorer.h>
#include <projectexplorer/projectmanager.h> #include <projectexplorer/projectmanager.h>
#include <utils/algorithm.h> #include <utils/algorithm.h>
#include <utils/commandline.h> #include <utils/commandline.h>
#include <utils/environment.h> #include <utils/environment.h>
@@ -43,7 +46,8 @@
#include <utils/pathchooser.h> #include <utils/pathchooser.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/qtcprocess.h> #include <utils/qtcprocess.h>
#include <utils/shellcommand.h>
#include <vcsbase/vcscommand.h>
#include <QApplication> #include <QApplication>
#include <QCheckBox> #include <QCheckBox>
@@ -152,13 +156,13 @@ void GitLabCloneDialog::cloneProject()
m_directoryLE->text(), extraArgs); m_directoryLE->text(), extraArgs);
const Utils::FilePath workingDirectory = m_pathChooser->absoluteFilePath(); const Utils::FilePath workingDirectory = m_pathChooser->absoluteFilePath();
m_command->setProgressiveOutput(true); 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); 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); 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); QApplication::setOverrideCursor(Qt::WaitCursor);
m_cloneOutput->clear(); m_cloneOutput->clear();

View File

@@ -39,9 +39,10 @@ namespace Utils {
class FancyLineEdit; class FancyLineEdit;
class InfoLabel; class InfoLabel;
class PathChooser; class PathChooser;
class ShellCommand;
} }
namespace VcsBase { class VcsCommand; }
namespace GitLab { namespace GitLab {
class Project; class Project;
@@ -66,7 +67,7 @@ private:
Utils::PathChooser *m_pathChooser = nullptr; Utils::PathChooser *m_pathChooser = nullptr;
Utils::FancyLineEdit *m_directoryLE = nullptr; Utils::FancyLineEdit *m_directoryLE = nullptr;
Utils::InfoLabel *m_infoLabel = nullptr; Utils::InfoLabel *m_infoLabel = nullptr;
Utils::ShellCommand *m_command = nullptr; VcsBase::VcsCommand *m_command = nullptr;
bool m_commandRunning = false; bool m_commandRunning = false;
}; };

View File

@@ -28,18 +28,18 @@
#include <coreplugin/idocument.h> #include <coreplugin/idocument.h>
#include <vcsbase/vcsoutputwindow.h>
#include <vcsbase/vcsbaseplugin.h>
#include <vcsbase/vcsbaseeditor.h>
#include <vcsbase/vcsbaseeditorconfig.h>
#include <vcsbase/vcsbasediffeditorcontroller.h>
#include <utils/commandline.h> #include <utils/commandline.h>
#include <utils/environment.h> #include <utils/environment.h>
#include <utils/fileutils.h> #include <utils/fileutils.h>
#include <utils/hostosinfo.h> #include <utils/hostosinfo.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/shellcommand.h>
#include <vcsbase/vcsbasediffeditorcontroller.h>
#include <vcsbase/vcsbaseeditor.h>
#include <vcsbase/vcsbaseeditorconfig.h>
#include <vcsbase/vcsbaseplugin.h>
#include <vcsbase/vcscommand.h>
#include <vcsbase/vcsoutputwindow.h>
#include <QDateTime> #include <QDateTime>
#include <QDir> #include <QDir>
@@ -118,9 +118,9 @@ bool MercurialClient::synchronousClone(const FilePath &workingDirectory,
{ {
Q_UNUSED(srcLocation) Q_UNUSED(srcLocation)
Q_UNUSED(extraOptions) Q_UNUSED(extraOptions)
const unsigned flags = ShellCommand::SshPasswordPrompt const unsigned flags = VcsCommand::SshPasswordPrompt
| ShellCommand::ShowStdOut | VcsCommand::ShowStdOut
| ShellCommand::ShowSuccessMessage; | VcsCommand::ShowSuccessMessage;
if (workingDirectory.exists()) { if (workingDirectory.exists()) {
// Let's make first init // Let's make first init
@@ -165,15 +165,15 @@ bool MercurialClient::synchronousPull(const FilePath &workingDir, const QString
QStringList args; QStringList args;
args << vcsCommandString(PullCommand) << extraOptions << srcLocation; args << vcsCommandString(PullCommand) << extraOptions << srcLocation;
// Disable UNIX terminals to suppress SSH prompting // Disable UNIX terminals to suppress SSH prompting
const unsigned flags = ShellCommand::SshPasswordPrompt const unsigned flags = VcsCommand::SshPasswordPrompt
| ShellCommand::ShowStdOut | VcsCommand::ShowStdOut
| ShellCommand::ShowSuccessMessage; | VcsCommand::ShowSuccessMessage;
// cause mercurial doesn`t understand LANG // cause mercurial doesn`t understand LANG
Environment env = Environment::systemEnvironment(); Environment env = Environment::systemEnvironment();
env.set("LANGUAGE", "C"); env.set("LANGUAGE", "C");
ShellCommand *command = VcsBaseClient::createVcsCommand(workingDir, env); VcsCommand *command = VcsBaseClient::createVcsCommand(workingDir, env);
command->addFlags(flags); command->addFlags(flags);
const CommandResult result = command->runCommand({vcsBinary(), args}, workingDir, vcsTimeoutS()); const CommandResult result = command->runCommand({vcsBinary(), args}, workingDir, vcsTimeoutS());
delete command; delete command;

View File

@@ -48,12 +48,12 @@
#include <utils/environment.h> #include <utils/environment.h>
#include <utils/parameteraction.h> #include <utils/parameteraction.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/shellcommand.h>
#include <vcsbase/basevcseditorfactory.h> #include <vcsbase/basevcseditorfactory.h>
#include <vcsbase/basevcssubmiteditorfactory.h> #include <vcsbase/basevcssubmiteditorfactory.h>
#include <vcsbase/vcsbaseconstants.h> #include <vcsbase/vcsbaseconstants.h>
#include <vcsbase/vcsbaseeditor.h> #include <vcsbase/vcsbaseeditor.h>
#include <vcsbase/vcscommand.h>
#include <vcsbase/vcsoutputwindow.h> #include <vcsbase/vcsoutputwindow.h>
#include <QAction> #include <QAction>
@@ -146,10 +146,10 @@ public:
void vcsAnnotate(const FilePath &filePath, int line) final; void vcsAnnotate(const FilePath &filePath, int line) final;
void vcsDescribe(const FilePath &source, const QString &id) final { m_client.view(source.toString(), id); } void vcsDescribe(const FilePath &source, const QString &id) final { m_client.view(source.toString(), id); }
ShellCommand *createInitialCheckoutCommand(const QString &url, VcsCommand *createInitialCheckoutCommand(const QString &url,
const Utils::FilePath &baseDirectory, const Utils::FilePath &baseDirectory,
const QString &localName, const QString &localName,
const QStringList &extraArgs) final; const QStringList &extraArgs) final;
bool sccManaged(const QString &filename); 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); m_client.annotate(filePath.parentDir(), filePath.fileName(), QString(), line);
} }
ShellCommand *MercurialPluginPrivate::createInitialCheckoutCommand(const QString &url, VcsCommand *MercurialPluginPrivate::createInitialCheckoutCommand(const QString &url,
const Utils::FilePath &baseDirectory, const Utils::FilePath &baseDirectory,
const QString &localName, const QString &localName,
const QStringList &extraArgs) const QStringList &extraArgs)
{ {
QStringList args; QStringList args;
args << QLatin1String("clone") << extraArgs << url << localName; args << QLatin1String("clone") << extraArgs << url << localName;

View File

@@ -29,12 +29,6 @@
#include <coreplugin/editormanager/editormanager.h> #include <coreplugin/editormanager/editormanager.h>
#include <vcsbase/vcsbaseconstants.h>
#include <vcsbase/vcsbasediffeditorcontroller.h>
#include <vcsbase/vcsbaseeditor.h>
#include <vcsbase/vcsbaseeditorconfig.h>
#include <vcsbase/vcsbaseplugin.h>
#include <diffeditor/diffeditorcontroller.h> #include <diffeditor/diffeditorcontroller.h>
#include <diffeditor/diffutils.h> #include <diffeditor/diffutils.h>
@@ -43,7 +37,13 @@
#include <utils/environment.h> #include <utils/environment.h>
#include <utils/hostosinfo.h> #include <utils/hostosinfo.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/shellcommand.h>
#include <vcsbase/vcsbaseconstants.h>
#include <vcsbase/vcsbasediffeditorcontroller.h>
#include <vcsbase/vcsbaseeditor.h>
#include <vcsbase/vcsbaseeditorconfig.h>
#include <vcsbase/vcsbaseplugin.h>
#include <vcsbase/vcscommand.h>
#include <QDir> #include <QDir>
#include <QFileInfo> #include <QFileInfo>
@@ -94,7 +94,7 @@ bool SubversionClient::doCommit(const FilePath &repositoryRoot,
<< commitMessageFile << commitMessageFile
<< escapeFiles(files); << escapeFiles(files);
const CommandResult result = vcsSynchronousExec(repositoryRoot, args, const CommandResult result = vcsSynchronousExec(repositoryRoot, args,
ShellCommand::ShowStdOut | ShellCommand::NoFullySync); VcsCommand::ShowStdOut | VcsCommand::NoFullySync);
return result.result() == ProcessResult::FinishedWithSuccess; return result.result() == ProcessResult::FinishedWithSuccess;
} }
@@ -222,7 +222,7 @@ void SubversionDiffEditorController::requestDescription()
args << m_authenticationOptions; args << m_authenticationOptions;
args << QLatin1String("-r"); args << QLatin1String("-r");
args << QString::number(m_changeNumber); args << QString::number(m_changeNumber);
runCommand(QList<QStringList>() << args, ShellCommand::SshPasswordPrompt); runCommand(QList<QStringList>() << args, VcsCommand::SshPasswordPrompt);
} }
void SubversionDiffEditorController::requestDiff() void SubversionDiffEditorController::requestDiff()

View File

@@ -31,15 +31,6 @@
#include "subversionsettings.h" #include "subversionsettings.h"
#include "subversionsubmiteditor.h" #include "subversionsubmiteditor.h"
#include <vcsbase/basevcseditorfactory.h>
#include <vcsbase/basevcssubmiteditorfactory.h>
#include <vcsbase/vcsbaseeditor.h>
#include <vcsbase/vcsbaseconstants.h>
#include <vcsbase/vcsbaseplugin.h>
#include <vcsbase/vcsoutputwindow.h>
#include <texteditor/textdocument.h>
#include <coreplugin/actionmanager/actioncontainer.h> #include <coreplugin/actionmanager/actioncontainer.h>
#include <coreplugin/actionmanager/actionmanager.h> #include <coreplugin/actionmanager/actionmanager.h>
#include <coreplugin/actionmanager/command.h> #include <coreplugin/actionmanager/command.h>
@@ -50,6 +41,8 @@
#include <coreplugin/locator/commandlocator.h> #include <coreplugin/locator/commandlocator.h>
#include <coreplugin/messagemanager.h> #include <coreplugin/messagemanager.h>
#include <texteditor/textdocument.h>
#include <utils/algorithm.h> #include <utils/algorithm.h>
#include <utils/commandline.h> #include <utils/commandline.h>
#include <utils/environment.h> #include <utils/environment.h>
@@ -57,9 +50,16 @@
#include <utils/hostosinfo.h> #include <utils/hostosinfo.h>
#include <utils/parameteraction.h> #include <utils/parameteraction.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/shellcommand.h>
#include <utils/stringutils.h> #include <utils/stringutils.h>
#include <vcsbase/basevcseditorfactory.h>
#include <vcsbase/basevcssubmiteditorfactory.h>
#include <vcsbase/vcsbaseeditor.h>
#include <vcsbase/vcsbaseconstants.h>
#include <vcsbase/vcsbaseplugin.h>
#include <vcsbase/vcscommand.h>
#include <vcsbase/vcsoutputwindow.h>
#include <QAction> #include <QAction>
#include <QDebug> #include <QDebug>
#include <QDir> #include <QDir>
@@ -108,7 +108,7 @@ const char CMD_ID_UPDATE[] = "Subversion.Update";
const char CMD_ID_COMMIT_PROJECT[] = "Subversion.CommitProject"; const char CMD_ID_COMMIT_PROJECT[] = "Subversion.CommitProject";
const char CMD_ID_DESCRIBE[] = "Subversion.Describe"; 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 struct SubversionResponse
{ {
@@ -224,10 +224,10 @@ public:
void vcsAnnotate(const FilePath &file, int line) final; void vcsAnnotate(const FilePath &file, int line) final;
void vcsDescribe(const FilePath &source, const QString &changeNr) final; void vcsDescribe(const FilePath &source, const QString &changeNr) final;
ShellCommand *createInitialCheckoutCommand(const QString &url, VcsCommand *createInitialCheckoutCommand(const QString &url,
const Utils::FilePath &baseDirectory, const Utils::FilePath &baseDirectory,
const QString &localName, const QString &localName,
const QStringList &extraArgs) final; const QStringList &extraArgs) final;
bool isVcsDirectory(const Utils::FilePath &fileName) const; bool isVcsDirectory(const Utils::FilePath &fileName) const;
@@ -875,7 +875,7 @@ void SubversionPluginPrivate::svnStatus(const FilePath &workingDir, const QStrin
if (!relativePath.isEmpty()) if (!relativePath.isEmpty())
args.append(SubversionClient::escapeFile(relativePath)); args.append(SubversionClient::escapeFile(relativePath));
VcsOutputWindow::setRepository(workingDir.toString()); VcsOutputWindow::setRepository(workingDir.toString());
runSvn(workingDir, args, ShellCommand::ShowStdOut | ShellCommand::ShowSuccessMessage); runSvn(workingDir, args, VcsCommand::ShowStdOut | VcsCommand::ShowSuccessMessage);
VcsOutputWindow::clearRepository(); VcsOutputWindow::clearRepository();
} }
@@ -929,7 +929,7 @@ void SubversionPluginPrivate::vcsAnnotateHelper(const FilePath &workingDir, cons
args.append(QDir::toNativeSeparators(SubversionClient::escapeFile(file))); args.append(QDir::toNativeSeparators(SubversionClient::escapeFile(file)));
const auto response = runSvn(workingDir, args, const auto response = runSvn(workingDir, args,
ShellCommand::SshPasswordPrompt | ShellCommand::ForceCLocale, 1, codec); VcsCommand::SshPasswordPrompt | VcsCommand::ForceCLocale, 1, codec);
if (response.error) if (response.error)
return; return;
@@ -1110,7 +1110,7 @@ bool SubversionPluginPrivate::vcsMove(const FilePath &workingDir, const QString
args << QDir::toNativeSeparators(SubversionClient::escapeFile(from)) args << QDir::toNativeSeparators(SubversionClient::escapeFile(from))
<< QDir::toNativeSeparators(SubversionClient::escapeFile(to)); << QDir::toNativeSeparators(SubversionClient::escapeFile(to));
const auto response = runSvn(workingDir, args, const auto response = runSvn(workingDir, args,
s_defaultFlags | ShellCommand::FullySynchronously); s_defaultFlags | VcsCommand::FullySynchronously);
return !response.error; return !response.error;
} }
@@ -1136,7 +1136,7 @@ bool SubversionPluginPrivate::vcsCheckout(const FilePath &directory, const QByte
args << QLatin1String(tempUrl.toEncoded()) << directory.toString(); 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; return !response.error;
} }
@@ -1264,10 +1264,10 @@ void SubversionPluginPrivate::vcsAnnotate(const FilePath &filePath, int line)
vcsAnnotateHelper(filePath.parentDir(), filePath.fileName(), QString(), line); vcsAnnotateHelper(filePath.parentDir(), filePath.fileName(), QString(), line);
} }
ShellCommand *SubversionPluginPrivate::createInitialCheckoutCommand(const QString &url, VcsCommand *SubversionPluginPrivate::createInitialCheckoutCommand(const QString &url,
const Utils::FilePath &baseDirectory, const Utils::FilePath &baseDirectory,
const QString &localName, const QString &localName,
const QStringList &extraArgs) const QStringList &extraArgs)
{ {
QStringList args; QStringList args;
args << QLatin1String("checkout"); args << QLatin1String("checkout");

View File

@@ -25,6 +25,7 @@ add_qtc_plugin(VcsBase
vcsbaseeditorconfig.cpp vcsbaseeditorconfig.h vcsbaseeditorconfig.cpp vcsbaseeditorconfig.h
vcsbaseplugin.cpp vcsbaseplugin.h vcsbaseplugin.cpp vcsbaseplugin.h
vcsbasesubmiteditor.cpp vcsbasesubmiteditor.h vcsbasesubmiteditor.cpp vcsbasesubmiteditor.h
vcscommand.cpp vcscommand.h
vcsoutputformatter.cpp vcsoutputformatter.h vcsoutputformatter.cpp vcsoutputformatter.h
vcsoutputwindow.cpp vcsoutputwindow.h vcsoutputwindow.cpp vcsoutputwindow.h
vcsplugin.cpp vcsplugin.h vcsplugin.cpp vcsplugin.h

View File

@@ -61,6 +61,8 @@ QtcPlugin {
"vcsbaseplugin.h", "vcsbaseplugin.h",
"vcsbasesubmiteditor.cpp", "vcsbasesubmiteditor.cpp",
"vcsbasesubmiteditor.h", "vcsbasesubmiteditor.h",
"vcscommand.cpp",
"vcscommand.h",
"vcsoutputformatter.cpp", "vcsoutputformatter.cpp",
"vcsoutputformatter.h", "vcsoutputformatter.h",
"vcsoutputwindow.cpp", "vcsoutputwindow.cpp",

View File

@@ -26,6 +26,7 @@
#include "vcsbaseclient.h" #include "vcsbaseclient.h"
#include "vcsbaseclientsettings.h" #include "vcsbaseclientsettings.h"
#include "vcsbaseeditorconfig.h" #include "vcsbaseeditorconfig.h"
#include "vcscommand.h"
#include "vcsplugin.h" #include "vcsplugin.h"
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
@@ -39,7 +40,6 @@
#include <utils/environment.h> #include <utils/environment.h>
#include <utils/globalfilechangeblocker.h> #include <utils/globalfilechangeblocker.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/shellcommand.h>
#include <vcsbase/vcsbaseeditor.h> #include <vcsbase/vcsbaseeditor.h>
#include <vcsbase/vcsoutputwindow.h> #include <vcsbase/vcsoutputwindow.h>
@@ -80,18 +80,18 @@ namespace VcsBase {
class VcsCommandDecorator : public QObject class VcsCommandDecorator : public QObject
{ {
public: public:
VcsCommandDecorator(ShellCommand *command); VcsCommandDecorator(VcsCommand *command);
~VcsCommandDecorator(); ~VcsCommandDecorator();
private: private:
void addTask(const QFuture<void> &future); void addTask(const QFuture<void> &future);
void postRunCommand(const FilePath &workingDirectory); void postRunCommand(const FilePath &workingDirectory);
ShellCommand *m_command; VcsCommand *m_command;
QFutureInterface<void> m_futureInterface; QFutureInterface<void> m_futureInterface;
}; };
VcsCommandDecorator::VcsCommandDecorator(ShellCommand *command) VcsCommandDecorator::VcsCommandDecorator(VcsCommand *command)
: QObject(command) : QObject(command)
, m_command(command) , m_command(command)
{ {
@@ -101,24 +101,24 @@ VcsCommandDecorator::VcsCommandDecorator(ShellCommand *command)
VcsOutputWindow::setRepository(m_command->defaultWorkingDirectory().toString()); VcsOutputWindow::setRepository(m_command->defaultWorkingDirectory().toString());
m_command->setDisableUnixTerminal(); m_command->setDisableUnixTerminal();
connect(m_command, &ShellCommand::started, this, [this] { connect(m_command, &VcsCommand::started, this, [this] {
if (m_command->flags() & ShellCommand::ExpectRepoChanges) if (m_command->flags() & VcsCommand::ExpectRepoChanges)
GlobalFileChangeBlocker::instance()->forceBlocked(true); GlobalFileChangeBlocker::instance()->forceBlocked(true);
}); });
connect(m_command, &ShellCommand::finished, this, [this] { connect(m_command, &VcsCommand::finished, this, [this] {
if (m_command->flags() & ShellCommand::ExpectRepoChanges) if (m_command->flags() & VcsCommand::ExpectRepoChanges)
GlobalFileChangeBlocker::instance()->forceBlocked(false); GlobalFileChangeBlocker::instance()->forceBlocked(false);
}); });
VcsOutputWindow *outputWindow = VcsOutputWindow::instance(); 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); outputWindow->append(t);
}); });
connect(m_command, &ShellCommand::appendSilently, outputWindow, &VcsOutputWindow::appendSilently); connect(m_command, &VcsCommand::appendSilently, outputWindow, &VcsOutputWindow::appendSilently);
connect(m_command, &ShellCommand::appendError, outputWindow, &VcsOutputWindow::appendError); connect(m_command, &VcsCommand::appendError, outputWindow, &VcsOutputWindow::appendError);
connect(m_command, &ShellCommand::appendCommand, outputWindow, &VcsOutputWindow::appendCommand); connect(m_command, &VcsCommand::appendCommand, outputWindow, &VcsOutputWindow::appendCommand);
connect(m_command, &ShellCommand::appendMessage, outputWindow, &VcsOutputWindow::appendMessage); connect(m_command, &VcsCommand::appendMessage, outputWindow, &VcsOutputWindow::appendMessage);
connect(m_command, &ShellCommand::executedAsync, this, &VcsCommandDecorator::addTask); connect(m_command, &VcsCommand::executedAsync, this, &VcsCommandDecorator::addTask);
const auto connection = connect(m_command, &ShellCommand::runCommandFinished, const auto connection = connect(m_command, &VcsCommand::runCommandFinished,
this, &VcsCommandDecorator::postRunCommand); this, &VcsCommandDecorator::postRunCommand);
connect(ICore::instance(), &ICore::coreAboutToClose, this, [this, connection] { connect(ICore::instance(), &ICore::coreAboutToClose, this, [this, connection] {
disconnect(connection); disconnect(connection);
@@ -133,7 +133,7 @@ VcsCommandDecorator::~VcsCommandDecorator()
void VcsCommandDecorator::addTask(const QFuture<void> &future) void VcsCommandDecorator::addTask(const QFuture<void> &future)
{ {
if ((m_command->flags() & ShellCommand::SuppressCommandLogging)) if ((m_command->flags() & VcsCommand::SuppressCommandLogging))
return; return;
const QString name = m_command->displayName(); const QString name = m_command->displayName();
@@ -149,7 +149,7 @@ void VcsCommandDecorator::addTask(const QFuture<void> &future)
void VcsCommandDecorator::postRunCommand(const FilePath &workingDirectory) void VcsCommandDecorator::postRunCommand(const FilePath &workingDirectory)
{ {
if (!(m_command->flags() & ShellCommand::ExpectRepoChanges)) if (!(m_command->flags() & VcsCommand::ExpectRepoChanges))
return; return;
// TODO tell the document manager that the directory now received all expected changes // TODO tell the document manager that the directory now received all expected changes
// Core::DocumentManager::unexpectDirectoryChange(d->m_workingDirectory); // Core::DocumentManager::unexpectDirectoryChange(d->m_workingDirectory);
@@ -174,7 +174,7 @@ FilePath VcsBaseClientImpl::vcsBinary() const
return m_baseSettings->binaryPath.filePath(); return m_baseSettings->binaryPath.filePath();
} }
ShellCommand *VcsBaseClientImpl::createCommand(const FilePath &workingDirectory, VcsCommand *VcsBaseClientImpl::createCommand(const FilePath &workingDirectory,
VcsBaseEditorWidget *editor, VcsBaseEditorWidget *editor,
JobOutputBindMode mode) const JobOutputBindMode mode) const
{ {
@@ -183,32 +183,32 @@ ShellCommand *VcsBaseClientImpl::createCommand(const FilePath &workingDirectory,
if (editor) if (editor)
editor->setCommand(cmd); editor->setCommand(cmd);
if (mode == VcsWindowOutputBind) { if (mode == VcsWindowOutputBind) {
cmd->addFlags(ShellCommand::ShowStdOut); cmd->addFlags(VcsCommand::ShowStdOut);
if (editor) // assume that the commands output is the important thing if (editor) // assume that the commands output is the important thing
cmd->addFlags(ShellCommand::SilentOutput); cmd->addFlags(VcsCommand::SilentOutput);
} else if (editor) { } else if (editor) {
connect(cmd, &ShellCommand::stdOutText, editor, &VcsBaseEditorWidget::setPlainText); connect(cmd, &VcsCommand::stdOutText, editor, &VcsBaseEditorWidget::setPlainText);
} }
return cmd; return cmd;
} }
ShellCommand *VcsBaseClientImpl::execBgCommand(const FilePath &workingDirectory, VcsCommand *VcsBaseClientImpl::execBgCommand(const FilePath &workingDirectory,
const QStringList &args, const QStringList &args,
const std::function<void (const QString &)> &outputCallback, const std::function<void (const QString &)> &outputCallback,
unsigned flags) const unsigned flags) const
{ {
ShellCommand *cmd = createCommand(workingDirectory); VcsCommand *cmd = createCommand(workingDirectory);
cmd->addFlags(flags | ShellCommand::SuppressCommandLogging cmd->addFlags(flags | VcsCommand::SuppressCommandLogging
| ShellCommand::SuppressStdErr | VcsCommand::SuppressStdErr
| ShellCommand::SuppressFailMessage); | VcsCommand::SuppressFailMessage);
cmd->addJob({vcsBinary(), args}); cmd->addJob({vcsBinary(), args});
connect(cmd, &ShellCommand::stdOutText, this, outputCallback); connect(cmd, &VcsCommand::stdOutText, this, outputCallback);
cmd->execute(); cmd->execute();
return cmd; return cmd;
} }
void VcsBaseClientImpl::enqueueJob(ShellCommand *cmd, const QStringList &args, void VcsBaseClientImpl::enqueueJob(VcsCommand *cmd, const QStringList &args,
const ExitCodeInterpreter &interpreter) const const ExitCodeInterpreter &interpreter) const
{ {
cmd->addJob({vcsBinary(), args}, vcsTimeoutS(), {}, interpreter); cmd->addJob({vcsBinary(), args}, vcsTimeoutS(), {}, interpreter);
@@ -249,7 +249,7 @@ CommandResult VcsBaseClientImpl::vcsFullySynchronousExec(const FilePath &working
CommandResult VcsBaseClientImpl::vcsFullySynchronousExec(const FilePath &workingDir, CommandResult VcsBaseClientImpl::vcsFullySynchronousExec(const FilePath &workingDir,
const CommandLine &cmdLine, unsigned flags, int timeoutS, QTextCodec *codec) const const CommandLine &cmdLine, unsigned flags, int timeoutS, QTextCodec *codec) const
{ {
ShellCommand command(workingDir, processEnvironment()); VcsCommand command(workingDir, processEnvironment());
new VcsCommandDecorator(&command); new VcsCommandDecorator(&command);
command.addFlags(flags); command.addFlags(flags);
if (codec) if (codec)
@@ -275,12 +275,12 @@ void VcsBaseClientImpl::annotateRevisionRequested(const FilePath &workingDirecto
annotate(workingDirectory, file, changeCopy, line); annotate(workingDirectory, file, changeCopy, line);
} }
ShellCommand *VcsBaseClientImpl::vcsExec(const FilePath &workingDirectory, VcsCommand *VcsBaseClientImpl::vcsExec(const FilePath &workingDirectory,
const QStringList &arguments, const QStringList &arguments,
VcsBaseEditorWidget *editor, bool useOutputToWindow, VcsBaseEditorWidget *editor, bool useOutputToWindow,
unsigned additionalFlags, const QVariant &cookie) const unsigned additionalFlags, const QVariant &cookie) const
{ {
ShellCommand *command = createCommand(workingDirectory, editor, VcsCommand *command = createCommand(workingDirectory, editor,
useOutputToWindow ? VcsWindowOutputBind : NoOutputBind); useOutputToWindow ? VcsWindowOutputBind : NoOutputBind);
command->setCookie(cookie); command->setCookie(cookie);
command->addFlags(additionalFlags); command->addFlags(additionalFlags);
@@ -296,7 +296,7 @@ CommandResult VcsBaseClientImpl::vcsSynchronousExec(const FilePath &workingDir,
QTextCodec *outputCodec) const QTextCodec *outputCodec) const
{ {
Environment env = processEnvironment(); Environment env = processEnvironment();
ShellCommand command(workingDir, env.isValid() ? env : Environment::systemEnvironment()); VcsCommand command(workingDir, env.isValid() ? env : Environment::systemEnvironment());
new VcsCommandDecorator(&command); new VcsCommandDecorator(&command);
command.addFlags(flags); command.addFlags(flags);
command.setCodec(outputCodec); command.setCodec(outputCodec);
@@ -308,10 +308,10 @@ int VcsBaseClientImpl::vcsTimeoutS() const
return m_baseSettings->timeout.value(); return m_baseSettings->timeout.value();
} }
ShellCommand *VcsBaseClientImpl::createVcsCommand(const FilePath &defaultWorkingDir, VcsCommand *VcsBaseClientImpl::createVcsCommand(const FilePath &defaultWorkingDir,
const Environment &environment) const Environment &environment)
{ {
ShellCommand *command = new ShellCommand(defaultWorkingDir, environment); VcsCommand *command = new VcsCommand(defaultWorkingDir, environment);
new VcsCommandDecorator(command); new VcsCommandDecorator(command);
return command; return command;
} }
@@ -421,9 +421,9 @@ bool VcsBaseClient::synchronousPull(const FilePath &workingDir,
QStringList args; QStringList args;
args << vcsCommandString(PullCommand) << extraOptions << srcLocation; args << vcsCommandString(PullCommand) << extraOptions << srcLocation;
// Disable UNIX terminals to suppress SSH prompting // Disable UNIX terminals to suppress SSH prompting
const unsigned flags = ShellCommand::SshPasswordPrompt const unsigned flags = VcsCommand::SshPasswordPrompt
| ShellCommand::ShowStdOut | VcsCommand::ShowStdOut
| ShellCommand::ShowSuccessMessage; | VcsCommand::ShowSuccessMessage;
const bool ok = vcsSynchronousExec(workingDir, args, flags).result() const bool ok = vcsSynchronousExec(workingDir, args, flags).result()
== ProcessResult::FinishedWithSuccess; == ProcessResult::FinishedWithSuccess;
if (ok) if (ok)
@@ -438,9 +438,9 @@ bool VcsBaseClient::synchronousPush(const FilePath &workingDir,
QStringList args; QStringList args;
args << vcsCommandString(PushCommand) << extraOptions << dstLocation; args << vcsCommandString(PushCommand) << extraOptions << dstLocation;
// Disable UNIX terminals to suppress SSH prompting // Disable UNIX terminals to suppress SSH prompting
const unsigned flags = ShellCommand::SshPasswordPrompt const unsigned flags = VcsCommand::SshPasswordPrompt
| ShellCommand::ShowStdOut | VcsCommand::ShowStdOut
| ShellCommand::ShowSuccessMessage; | VcsCommand::ShowSuccessMessage;
return vcsSynchronousExec(workingDir, args, flags).result() return vcsSynchronousExec(workingDir, args, flags).result()
== ProcessResult::FinishedWithSuccess; == ProcessResult::FinishedWithSuccess;
} }
@@ -461,7 +461,7 @@ VcsBaseEditorWidget *VcsBaseClient::annotate(
VcsBaseEditor::getCodec(source), VcsBaseEditor::getCodec(source),
vcsCmdString.toLatin1().constData(), id); vcsCmdString.toLatin1().constData(), id);
ShellCommand *cmd = createCommand(workingDir, editor); VcsCommand *cmd = createCommand(workingDir, editor);
cmd->setCookie(lineNumber); cmd->setCookie(lineNumber);
enqueueJob(cmd, args); enqueueJob(cmd, args);
return editor; return editor;
@@ -503,7 +503,7 @@ void VcsBaseClient::diff(const FilePath &workingDir, const QStringList &files,
args << files; args << files;
QTextCodec *codec = source.isEmpty() ? static_cast<QTextCodec *>(nullptr) QTextCodec *codec = source.isEmpty() ? static_cast<QTextCodec *>(nullptr)
: VcsBaseEditor::getCodec(source); : VcsBaseEditor::getCodec(source);
ShellCommand *command = createCommand(workingDir, editor); VcsCommand *command = createCommand(workingDir, editor);
command->setCodec(codec); command->setCodec(codec);
enqueueJob(command, args, exitCodeInterpreter(DiffCommand)); enqueueJob(command, args, exitCodeInterpreter(DiffCommand));
} }
@@ -553,9 +553,9 @@ void VcsBaseClient::revertFile(const FilePath &workingDir,
QStringList args(vcsCommandString(RevertCommand)); QStringList args(vcsCommandString(RevertCommand));
args << revisionSpec(revision) << extraOptions << file; args << revisionSpec(revision) << extraOptions << file;
// Indicate repository change or file list // Indicate repository change or file list
ShellCommand *cmd = createCommand(workingDir); VcsCommand *cmd = createCommand(workingDir);
cmd->setCookie(QStringList(workingDir.pathAppended(file).toString())); 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) if (success)
emit changed(cookie); emit changed(cookie);
}, Qt::QueuedConnection); }, Qt::QueuedConnection);
@@ -569,9 +569,9 @@ void VcsBaseClient::revertAll(const FilePath &workingDir,
QStringList args(vcsCommandString(RevertCommand)); QStringList args(vcsCommandString(RevertCommand));
args << revisionSpec(revision) << extraOptions; args << revisionSpec(revision) << extraOptions;
// Indicate repository change or file list // Indicate repository change or file list
ShellCommand *cmd = createCommand(workingDir); VcsCommand *cmd = createCommand(workingDir);
cmd->setCookie(QStringList(workingDir.toString())); 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) if (success)
emit changed(cookie); emit changed(cookie);
}, Qt::QueuedConnection); }, Qt::QueuedConnection);
@@ -585,8 +585,8 @@ void VcsBaseClient::status(const FilePath &workingDir,
QStringList args(vcsCommandString(StatusCommand)); QStringList args(vcsCommandString(StatusCommand));
args << extraOptions << file; args << extraOptions << file;
VcsOutputWindow::setRepository(workingDir.toString()); VcsOutputWindow::setRepository(workingDir.toString());
ShellCommand *cmd = createCommand(workingDir, nullptr, VcsWindowOutputBind); VcsCommand *cmd = createCommand(workingDir, nullptr, VcsWindowOutputBind);
connect(cmd, &ShellCommand::finished, connect(cmd, &VcsCommand::finished,
VcsOutputWindow::instance(), &VcsOutputWindow::clearRepository, VcsOutputWindow::instance(), &VcsOutputWindow::clearRepository,
Qt::QueuedConnection); Qt::QueuedConnection);
enqueueJob(cmd, args); enqueueJob(cmd, args);
@@ -596,8 +596,8 @@ void VcsBaseClient::emitParsedStatus(const FilePath &repository, const QStringLi
{ {
QStringList args(vcsCommandString(StatusCommand)); QStringList args(vcsCommandString(StatusCommand));
args << extraOptions; args << extraOptions;
ShellCommand *cmd = createCommand(repository); VcsCommand *cmd = createCommand(repository);
connect(cmd, &ShellCommand::stdOutText, this, &VcsBaseClient::statusParser); connect(cmd, &VcsCommand::stdOutText, this, &VcsBaseClient::statusParser);
enqueueJob(cmd, args); enqueueJob(cmd, args);
} }
@@ -670,9 +670,9 @@ void VcsBaseClient::update(const FilePath &repositoryRoot, const QString &revisi
{ {
QStringList args(vcsCommandString(UpdateCommand)); QStringList args(vcsCommandString(UpdateCommand));
args << revisionSpec(revision) << extraOptions; args << revisionSpec(revision) << extraOptions;
ShellCommand *cmd = createCommand(repositoryRoot); VcsCommand *cmd = createCommand(repositoryRoot);
cmd->setCookie(repositoryRoot.toString()); 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) if (success)
emit changed(cookie); emit changed(cookie);
}, Qt::QueuedConnection); }, Qt::QueuedConnection);
@@ -694,9 +694,9 @@ void VcsBaseClient::commit(const FilePath &repositoryRoot,
// for example) // for example)
QStringList args(vcsCommandString(CommitCommand)); QStringList args(vcsCommandString(CommitCommand));
args << extraOptions << files; args << extraOptions << files;
ShellCommand *cmd = createCommand(repositoryRoot, nullptr, VcsWindowOutputBind); VcsCommand *cmd = createCommand(repositoryRoot, nullptr, VcsWindowOutputBind);
if (!commitMessageFile.isEmpty()) if (!commitMessageFile.isEmpty())
connect(cmd, &ShellCommand::finished, [commitMessageFile] { QFile(commitMessageFile).remove(); }); connect(cmd, &VcsCommand::finished, [commitMessageFile] { QFile(commitMessageFile).remove(); });
enqueueJob(cmd, args); enqueueJob(cmd, args);
} }

View File

@@ -44,15 +44,12 @@ class QTextCodec;
class QToolBar; class QToolBar;
QT_END_NAMESPACE QT_END_NAMESPACE
namespace Utils {
class CommandResult;
class ShellCommand;
}
namespace VcsBase { namespace VcsBase {
class CommandResult;
class VcsBaseEditorConfig; class VcsBaseEditorConfig;
class VcsBaseEditorWidget; class VcsBaseEditorWidget;
class VcsCommand;
class VCSBASE_EXPORT VcsBaseClientImpl : public QObject class VCSBASE_EXPORT VcsBaseClientImpl : public QObject
{ {
@@ -72,24 +69,24 @@ public:
VcsWindowOutputBind VcsWindowOutputBind
}; };
static Utils::ShellCommand *createVcsCommand(const Utils::FilePath &defaultWorkingDir, static VcsCommand *createVcsCommand(const Utils::FilePath &defaultWorkingDir,
const Utils::Environment &environment); const Utils::Environment &environment);
VcsBaseEditorWidget *createVcsEditor(Utils::Id kind, QString title, VcsBaseEditorWidget *createVcsEditor(Utils::Id kind, QString title,
const QString &source, QTextCodec *codec, const QString &source, QTextCodec *codec,
const char *registerDynamicProperty, const char *registerDynamicProperty,
const QString &dynamicPropertyValue) const; const QString &dynamicPropertyValue) const;
Utils::ShellCommand *createCommand(const Utils::FilePath &workingDirectory, VcsCommand *createCommand(const Utils::FilePath &workingDirectory,
VcsBaseEditorWidget *editor = nullptr, VcsBaseEditorWidget *editor = nullptr,
JobOutputBindMode mode = NoOutputBind) const; JobOutputBindMode mode = NoOutputBind) const;
Utils::ShellCommand *execBgCommand(const Utils::FilePath &workingDirectory, VcsCommand *execBgCommand(const Utils::FilePath &workingDirectory,
const QStringList &args, const QStringList &args,
const std::function<void (const QString &)> &outputCallback, const std::function<void (const QString &)> &outputCallback,
unsigned flags = 0) const; unsigned flags = 0) const;
void enqueueJob(Utils::ShellCommand *cmd, const QStringList &args, void enqueueJob(VcsCommand *cmd, const QStringList &args,
const Utils::ExitCodeInterpreter &interpreter = {}) const; const Utils::ExitCodeInterpreter &interpreter = {}) const;
virtual Utils::Environment processEnvironment() const; virtual Utils::Environment processEnvironment() const;
@@ -106,20 +103,20 @@ public:
static QString stripLastNewline(const QString &in); static QString stripLastNewline(const QString &in);
// Fully synchronous VCS execution (QProcess-based) // Fully synchronous VCS execution (QProcess-based)
Utils::CommandResult vcsFullySynchronousExec(const Utils::FilePath &workingDir, CommandResult vcsFullySynchronousExec(const Utils::FilePath &workingDir,
const QStringList &args, unsigned flags = 0, const QStringList &args, unsigned flags = 0,
int timeoutS = -1, QTextCodec *codec = nullptr) const; int timeoutS = -1, QTextCodec *codec = nullptr) const;
Utils::CommandResult vcsFullySynchronousExec(const Utils::FilePath &workingDir, CommandResult vcsFullySynchronousExec(const Utils::FilePath &workingDir,
const Utils::CommandLine &cmdLine, unsigned flags = 0, const Utils::CommandLine &cmdLine, unsigned flags = 0,
int timeoutS = -1, QTextCodec *codec = nullptr) const; int timeoutS = -1, QTextCodec *codec = nullptr) const;
// Simple helper to execute a single command using createCommand and enqueueJob. // Simple helper to execute a single command using createCommand and enqueueJob.
Utils::ShellCommand *vcsExec(const Utils::FilePath &workingDirectory, VcsCommand *vcsExec(const Utils::FilePath &workingDirectory,
const QStringList &arguments, const QStringList &arguments,
VcsBaseEditorWidget *editor = nullptr, VcsBaseEditorWidget *editor = nullptr,
bool useOutputToWindow = false, bool useOutputToWindow = false,
unsigned additionalFlags = 0, unsigned additionalFlags = 0,
const QVariant &cookie = {}) const; const QVariant &cookie = {}) const;
protected: protected:
void resetCachedVcsInfo(const Utils::FilePath &workingDir); void resetCachedVcsInfo(const Utils::FilePath &workingDir);
@@ -128,10 +125,10 @@ protected:
// Synchronous VCS execution using Utils::SynchronousProcess, with // Synchronous VCS execution using Utils::SynchronousProcess, with
// log windows updating (using VcsBasePlugin::runVcs with flags) // log windows updating (using VcsBasePlugin::runVcs with flags)
Utils::CommandResult vcsSynchronousExec(const Utils::FilePath &workingDir, CommandResult vcsSynchronousExec(const Utils::FilePath &workingDir,
const QStringList &args, const QStringList &args,
unsigned flags = 0, unsigned flags = 0,
QTextCodec *outputCodec = nullptr) const; QTextCodec *outputCodec = nullptr) const;
private: private:
void saveSettings(); void saveSettings();

View File

@@ -25,16 +25,17 @@
#include "vcsbasediffeditorcontroller.h" #include "vcsbasediffeditorcontroller.h"
#include "vcsbaseclient.h" #include "vcsbaseclient.h"
#include "vcscommand.h"
#include <coreplugin/editormanager/editormanager.h> #include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/progressmanager/progressmanager.h> #include <coreplugin/progressmanager/progressmanager.h>
#include <diffeditor/diffutils.h> #include <diffeditor/diffutils.h>
#include <utils/commandline.h> #include <utils/commandline.h>
#include <utils/environment.h> #include <utils/environment.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/runextensions.h> #include <utils/runextensions.h>
#include <utils/shellcommand.h>
#include <QPointer> #include <QPointer>
@@ -73,7 +74,7 @@ static void readPatch(QFutureInterface<QList<FileData>> &futureInterface,
class VcsCommandResultProxy : public QObject { class VcsCommandResultProxy : public QObject {
Q_OBJECT Q_OBJECT
public: public:
VcsCommandResultProxy(ShellCommand *command, VcsBaseDiffEditorControllerPrivate *target); VcsCommandResultProxy(VcsCommand *command, VcsBaseDiffEditorControllerPrivate *target);
private: private:
void storeOutput(const QString &output); void storeOutput(const QString &output);
void commandFinished(bool success); void commandFinished(bool success);
@@ -103,23 +104,23 @@ public:
QString m_startupFile; QString m_startupFile;
QString m_output; QString m_output;
QString m_displayName; QString m_displayName;
QPointer<ShellCommand> m_command; QPointer<VcsCommand> m_command;
QPointer<VcsCommandResultProxy> m_commandResultProxy; QPointer<VcsCommandResultProxy> m_commandResultProxy;
QFutureWatcher<QList<FileData>> *m_processWatcher = nullptr; QFutureWatcher<QList<FileData>> *m_processWatcher = nullptr;
}; };
///////////////////// /////////////////////
VcsCommandResultProxy::VcsCommandResultProxy(ShellCommand *command, VcsCommandResultProxy::VcsCommandResultProxy(VcsCommand *command,
VcsBaseDiffEditorControllerPrivate *target) VcsBaseDiffEditorControllerPrivate *target)
: QObject(target->q) : QObject(target->q)
, m_target(target) , m_target(target)
{ {
connect(command, &ShellCommand::stdOutText, connect(command, &VcsCommand::stdOutText,
this, &VcsCommandResultProxy::storeOutput); this, &VcsCommandResultProxy::storeOutput);
connect(command, &ShellCommand::finished, connect(command, &VcsCommand::finished,
this, &VcsCommandResultProxy::commandFinished); this, &VcsCommandResultProxy::commandFinished);
connect(command, &ShellCommand::destroyed, connect(command, &VcsCommand::destroyed,
this, &QObject::deleteLater); this, &QObject::deleteLater);
} }

View File

@@ -30,6 +30,7 @@
#include "diffandloghighlighter.h" #include "diffandloghighlighter.h"
#include "vcsbaseeditorconfig.h" #include "vcsbaseeditorconfig.h"
#include "vcsbaseplugin.h" #include "vcsbaseplugin.h"
#include "vcscommand.h"
#include <coreplugin/editormanager/editormanager.h> #include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/editormanager/ieditorfactory.h> #include <coreplugin/editormanager/ieditorfactory.h>
@@ -52,7 +53,6 @@
#include <utils/algorithm.h> #include <utils/algorithm.h>
#include <utils/progressindicator.h> #include <utils/progressindicator.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/shellcommand.h>
#include <utils/stringutils.h> #include <utils/stringutils.h>
#include <QAction> #include <QAction>
@@ -561,7 +561,7 @@ public:
QString m_annotatePreviousRevisionTextFormat; QString m_annotatePreviousRevisionTextFormat;
VcsBaseEditorConfig *m_config = nullptr; VcsBaseEditorConfig *m_config = nullptr;
QList<AbstractTextCursorHandler *> m_textCursorHandlers; QList<AbstractTextCursorHandler *> m_textCursorHandlers;
QPointer<ShellCommand> m_command; QPointer<VcsCommand> m_command;
VcsBaseEditorWidget::DescribeFunc m_describeFunc = nullptr; VcsBaseEditorWidget::DescribeFunc m_describeFunc = nullptr;
ProgressIndicator *m_progressIndicator = nullptr; ProgressIndicator *m_progressIndicator = nullptr;
bool m_fileLogAnnotateEnabled = false; bool m_fileLogAnnotateEnabled = false;
@@ -1408,7 +1408,7 @@ VcsBaseEditorConfig *VcsBaseEditorWidget::editorConfig() const
return d->m_config; return d->m_config;
} }
void VcsBaseEditorWidget::setCommand(ShellCommand *command) void VcsBaseEditorWidget::setCommand(VcsCommand *command)
{ {
if (d->m_command) { if (d->m_command) {
d->m_command->abort(); d->m_command->abort();
@@ -1418,7 +1418,7 @@ void VcsBaseEditorWidget::setCommand(ShellCommand *command)
if (command) { if (command) {
d->m_progressIndicator = new ProgressIndicator(ProgressIndicatorSize::Large); d->m_progressIndicator = new ProgressIndicator(ProgressIndicatorSize::Large);
d->m_progressIndicator->attachToWidget(this); 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); QTimer::singleShot(100, this, &VcsBaseEditorWidget::showProgressIndicator);
} }
} }

View File

@@ -36,8 +36,6 @@ QT_BEGIN_NAMESPACE
class QTextCursor; class QTextCursor;
QT_END_NAMESPACE QT_END_NAMESPACE
namespace Utils { class ShellCommand; }
namespace VcsBase { namespace VcsBase {
namespace Internal { namespace Internal {
@@ -48,6 +46,7 @@ class VcsBaseEditorWidgetPrivate;
class BaseAnnotationHighlighter; class BaseAnnotationHighlighter;
class VcsBaseEditorConfig; class VcsBaseEditorConfig;
class VcsBaseEditorWidget; class VcsBaseEditorWidget;
class VcsCommand;
class VcsEditorFactory; class VcsEditorFactory;
// Documentation inside // Documentation inside
@@ -213,7 +212,7 @@ public:
void setEditorConfig(VcsBaseEditorConfig *config); void setEditorConfig(VcsBaseEditorConfig *config);
VcsBaseEditorConfig *editorConfig() const; VcsBaseEditorConfig *editorConfig() const;
void setCommand(Utils::ShellCommand *command); void setCommand(VcsCommand *command);
virtual void setPlainText(const QString &text); virtual void setPlainText(const QString &text);

View File

@@ -23,12 +23,12 @@
** **
****************************************************************************/ ****************************************************************************/
#include "shellcommand.h" #include "vcscommand.h"
#include "environment.h" #include <utils/environment.h>
#include "qtcassert.h" #include <utils/qtcassert.h>
#include "qtcprocess.h" #include <utils/qtcprocess.h>
#include "runextensions.h" #include <utils/runextensions.h>
#include <QFuture> #include <QFuture>
#include <QFutureWatcher> #include <QFutureWatcher>
@@ -56,10 +56,12 @@
when a progress string is detected. when a progress string is detected.
*/ */
namespace Utils { using namespace Utils;
namespace VcsBase {
namespace Internal { namespace Internal {
class ShellCommandPrivate class VcsCommandPrivate
{ {
public: public:
struct Job { struct Job {
@@ -72,16 +74,16 @@ public:
int timeoutS; int timeoutS;
}; };
ShellCommandPrivate(const FilePath &defaultWorkingDirectory, const Environment &environment) VcsCommandPrivate(const FilePath &defaultWorkingDirectory, const Environment &environment)
: m_defaultWorkingDirectory(defaultWorkingDirectory), : m_defaultWorkingDirectory(defaultWorkingDirectory),
m_environment(environment) m_environment(environment)
{} {}
~ShellCommandPrivate() { delete m_progressParser; } ~VcsCommandPrivate() { delete m_progressParser; }
Environment environment() Environment environment()
{ {
if (!(m_flags & ShellCommand::ForceCLocale)) if (!(m_flags & VcsCommand::ForceCLocale))
return m_environment; return m_environment;
m_environment.set("LANG", "C"); m_environment.set("LANG", "C");
@@ -107,7 +109,7 @@ public:
bool m_disableUnixTerminal = false; 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) : int t, const ExitCodeInterpreter &interpreter) :
workingDirectory(wd), workingDirectory(wd),
command(command), command(command),
@@ -121,23 +123,23 @@ ShellCommandPrivate::Job::Job(const FilePath &wd, const CommandLine &command,
} // namespace Internal } // namespace Internal
ShellCommand::ShellCommand(const FilePath &workingDirectory, const Environment &environment) : VcsCommand::VcsCommand(const FilePath &workingDirectory, const Environment &environment) :
d(new Internal::ShellCommandPrivate(workingDirectory, environment)) d(new Internal::VcsCommandPrivate(workingDirectory, environment))
{ {
connect(&d->m_watcher, &QFutureWatcher<void>::canceled, this, &ShellCommand::cancel); connect(&d->m_watcher, &QFutureWatcher<void>::canceled, this, &VcsCommand::cancel);
} }
ShellCommand::~ShellCommand() VcsCommand::~VcsCommand()
{ {
delete d; delete d;
} }
QString ShellCommand::displayName() const QString VcsCommand::displayName() const
{ {
if (!d->m_displayName.isEmpty()) if (!d->m_displayName.isEmpty())
return d->m_displayName; return d->m_displayName;
if (!d->m_jobs.isEmpty()) { 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(); QString result = job.command.executable().baseName();
if (!result.isEmpty()) if (!result.isEmpty())
result[0] = result.at(0).toTitleCase(); result[0] = result.at(0).toTitleCase();
@@ -152,98 +154,98 @@ QString ShellCommand::displayName() const
return tr("Unknown"); return tr("Unknown");
} }
void ShellCommand::setDisplayName(const QString &name) void VcsCommand::setDisplayName(const QString &name)
{ {
d->m_displayName = name; d->m_displayName = name;
} }
const FilePath &ShellCommand::defaultWorkingDirectory() const const FilePath &VcsCommand::defaultWorkingDirectory() const
{ {
return d->m_defaultWorkingDirectory; return d->m_defaultWorkingDirectory;
} }
Environment ShellCommand::environment() const Environment VcsCommand::environment() const
{ {
return d->m_environment; return d->m_environment;
} }
void ShellCommand::setEnvironment(const Environment &env) void VcsCommand::setEnvironment(const Environment &env)
{ {
d->m_environment = env; d->m_environment = env;
} }
int ShellCommand::defaultTimeoutS() const int VcsCommand::defaultTimeoutS() const
{ {
return d->m_defaultTimeoutS; return d->m_defaultTimeoutS;
} }
void ShellCommand::setDefaultTimeoutS(int timeout) void VcsCommand::setDefaultTimeoutS(int timeout)
{ {
d->m_defaultTimeoutS = timeout; d->m_defaultTimeoutS = timeout;
} }
unsigned ShellCommand::flags() const unsigned VcsCommand::flags() const
{ {
return d->m_flags; return d->m_flags;
} }
void ShellCommand::addFlags(unsigned f) void VcsCommand::addFlags(unsigned f)
{ {
d->m_flags |= f; d->m_flags |= f;
} }
void ShellCommand::addJob(const CommandLine &command, void VcsCommand::addJob(const CommandLine &command,
const FilePath &workingDirectory, const FilePath &workingDirectory,
const ExitCodeInterpreter &interpreter) const ExitCodeInterpreter &interpreter)
{ {
addJob(command, defaultTimeoutS(), workingDirectory, 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 FilePath &workingDirectory,
const ExitCodeInterpreter &interpreter) 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)); timeoutS, interpreter));
} }
void ShellCommand::execute() void VcsCommand::execute()
{ {
if (d->m_jobs.empty()) if (d->m_jobs.empty())
return; return;
QFuture<void> task = runAsync(&ShellCommand::run, this); QFuture<void> task = runAsync(&VcsCommand::run, this);
d->m_watcher.setFuture(task); d->m_watcher.setFuture(task);
emit executedAsync(task); emit executedAsync(task);
} }
void ShellCommand::abort() void VcsCommand::abort()
{ {
d->m_aborted = true; d->m_aborted = true;
d->m_watcher.future().cancel(); d->m_watcher.future().cancel();
} }
void ShellCommand::cancel() void VcsCommand::cancel()
{ {
emit terminate(); emit terminate();
} }
int ShellCommand::timeoutS() const int VcsCommand::timeoutS() const
{ {
return std::accumulate(d->m_jobs.cbegin(), d->m_jobs.cend(), 0, 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; return sum + job.timeoutS;
}); });
} }
FilePath ShellCommand::workDirectory(const FilePath &wd) const FilePath VcsCommand::workDirectory(const FilePath &wd) const
{ {
if (!wd.isEmpty()) if (!wd.isEmpty())
return wd; return wd;
return defaultWorkingDirectory(); return defaultWorkingDirectory();
} }
void ShellCommand::run(QFutureInterface<void> &future) void VcsCommand::run(QFutureInterface<void> &future)
{ {
// Check that the binary path is not empty // Check that the binary path is not empty
QTC_ASSERT(!d->m_jobs.isEmpty(), return); QTC_ASSERT(!d->m_jobs.isEmpty(), return);
@@ -259,7 +261,7 @@ void ShellCommand::run(QFutureInterface<void> &future)
const int count = d->m_jobs.size(); const int count = d->m_jobs.size();
bool lastExecSuccess = true; bool lastExecSuccess = true;
for (int j = 0; j < count; j++) { 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, const CommandResult result = runCommand(job.command, job.workingDirectory,
job.timeoutS, job.exitCodeInterpreter); job.timeoutS, job.exitCodeInterpreter);
stdOut += result.cleanedStdOut(); stdOut += result.cleanedStdOut();
@@ -289,7 +291,7 @@ void ShellCommand::run(QFutureInterface<void> &future)
this->deleteLater(); 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) int timeoutS, const ExitCodeInterpreter &interpreter)
{ {
QtcProcess proc; QtcProcess proc;
@@ -336,7 +338,7 @@ CommandResult ShellCommand::runCommand(const CommandLine &command, const FilePat
return CommandResult(proc); return CommandResult(proc);
} }
void ShellCommand::runFullySynchronous(QtcProcess &process) void VcsCommand::runFullySynchronous(QtcProcess &process)
{ {
process.runBlocking(); 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.stop();
process.waitForFinished(); process.waitForFinished();
}); });
@@ -392,44 +394,44 @@ void ShellCommand::runSynchronous(QtcProcess &process)
process.runBlocking(EventLoopMode::On); process.runBlocking(EventLoopMode::On);
} }
const QVariant &ShellCommand::cookie() const const QVariant &VcsCommand::cookie() const
{ {
return d->m_cookie; return d->m_cookie;
} }
void ShellCommand::setCookie(const QVariant &cookie) void VcsCommand::setCookie(const QVariant &cookie)
{ {
d->m_cookie = cookie; d->m_cookie = cookie;
} }
QTextCodec *ShellCommand::codec() const QTextCodec *VcsCommand::codec() const
{ {
return d->m_codec; return d->m_codec;
} }
void ShellCommand::setCodec(QTextCodec *codec) void VcsCommand::setCodec(QTextCodec *codec)
{ {
d->m_codec = codec; d->m_codec = codec;
} }
//! Use \a parser to parse progress data from stdout. Command takes ownership of \a parser //! 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); QTC_ASSERT(!d->m_progressParser, return);
d->m_progressParser = parser; d->m_progressParser = parser;
} }
bool ShellCommand::hasProgressParser() const bool VcsCommand::hasProgressParser() const
{ {
return d->m_progressParser; return d->m_progressParser;
} }
void ShellCommand::setProgressiveOutput(bool progressive) void VcsCommand::setProgressiveOutput(bool progressive)
{ {
d->m_progressiveOutput = progressive; d->m_progressiveOutput = progressive;
} }
void ShellCommand::setDisableUnixTerminal() void VcsCommand::setDisableUnixTerminal()
{ {
d->m_disableUnixTerminal = true; d->m_disableUnixTerminal = true;
} }
@@ -467,4 +469,4 @@ CommandResult::CommandResult(const QtcProcess &process)
, m_rawStdOut(process.rawStdOut()) , m_rawStdOut(process.rawStdOut())
{} {}
} // namespace Utils } // namespace VcsBase

View File

@@ -25,10 +25,10 @@
#pragma once #pragma once
#include "utils_global.h" #include "vcsbase_global.h"
#include "filepath.h" #include <utils/filepath.h>
#include "processenums.h" #include <utils/processenums.h>
#include <QObject> #include <QObject>
@@ -43,14 +43,16 @@ class QTextCodec;
QT_END_NAMESPACE QT_END_NAMESPACE
namespace Utils { namespace Utils {
class CommandLine; class CommandLine;
class Environment; class Environment;
class QtcProcess; class QtcProcess;
}
namespace Internal { class ShellCommandPrivate; } namespace VcsBase {
class QTCREATOR_UTILS_EXPORT ProgressParser namespace Internal { class VcsCommandPrivate; }
class VCSBASE_EXPORT ProgressParser
{ {
public: public:
ProgressParser(); ProgressParser();
@@ -65,16 +67,16 @@ private:
QFutureInterface<void> *m_future; QFutureInterface<void> *m_future;
QMutex *m_futureMutex = nullptr; QMutex *m_futureMutex = nullptr;
friend class ShellCommand; friend class VcsCommand;
}; };
class QTCREATOR_UTILS_EXPORT CommandResult class VCSBASE_EXPORT CommandResult
{ {
public: public:
CommandResult() = default; 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; } int exitCode() const { return m_exitCode; }
QString exitMessage() const { return m_exitMessage; } QString exitMessage() const { return m_exitMessage; }
@@ -84,7 +86,7 @@ public:
QByteArray rawStdOut() const { return m_rawStdOut; } QByteArray rawStdOut() const { return m_rawStdOut; }
private: private:
ProcessResult m_result = ProcessResult::StartFailed; Utils::ProcessResult m_result = Utils::ProcessResult::StartFailed;
int m_exitCode = 0; int m_exitCode = 0;
QString m_exitMessage; QString m_exitMessage;
@@ -94,7 +96,7 @@ private:
QByteArray m_rawStdOut; QByteArray m_rawStdOut;
}; };
class QTCREATOR_UTILS_EXPORT ShellCommand final : public QObject class VCSBASE_EXPORT VcsCommand final : public QObject
{ {
Q_OBJECT Q_OBJECT
@@ -118,23 +120,23 @@ public:
}; };
ShellCommand(const FilePath &workingDirectory, const Environment &environment); VcsCommand(const Utils::FilePath &workingDirectory, const Utils::Environment &environment);
~ShellCommand() override; ~VcsCommand() override;
QString displayName() const; QString displayName() const;
void setDisplayName(const QString &name); void setDisplayName(const QString &name);
const FilePath &defaultWorkingDirectory() const; const Utils::FilePath &defaultWorkingDirectory() const;
Environment environment() const; Utils::Environment environment() const;
void setEnvironment(const Environment &env); void setEnvironment(const Utils::Environment &env);
void addJob(const CommandLine &command, void addJob(const Utils::CommandLine &command,
const FilePath &workingDirectory = {}, const Utils::FilePath &workingDirectory = {},
const ExitCodeInterpreter &interpreter = {}); const Utils::ExitCodeInterpreter &interpreter = {});
void addJob(const CommandLine &command, int timeoutS, void addJob(const Utils::CommandLine &command, int timeoutS,
const FilePath &workingDirectory = {}, const Utils::FilePath &workingDirectory = {},
const ExitCodeInterpreter &interpreter = {}); const Utils::ExitCodeInterpreter &interpreter = {});
void execute(); // Execute tasks asynchronously! void execute(); // Execute tasks asynchronously!
void abort(); void abort();
@@ -157,8 +159,9 @@ public:
// This is called once per job in a thread. // This is called once per job in a thread.
// When called from the UI thread it will execute fully synchronously, so no signals will // When called from the UI thread it will execute fully synchronously, so no signals will
// be triggered! // be triggered!
CommandResult runCommand(const CommandLine &command, const FilePath &workingDirectory = {}, CommandResult runCommand(const Utils::CommandLine &command,
int timeoutS = 10, const ExitCodeInterpreter &interpreter = {}); const Utils::FilePath &workingDirectory = {},
int timeoutS = 10, const Utils::ExitCodeInterpreter &interpreter = {});
void cancel(); void cancel();
@@ -184,15 +187,15 @@ signals:
void runCommandFinished(const Utils::FilePath &workingDirectory); void runCommandFinished(const Utils::FilePath &workingDirectory);
private: private:
FilePath workDirectory(const FilePath &wd) const; Utils::FilePath workDirectory(const Utils::FilePath &wd) const;
void run(QFutureInterface<void> &future); void run(QFutureInterface<void> &future);
// Run without a event loop in fully blocking mode. No signals will be delivered. // 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. // 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 } // namespace Utils

View File

@@ -24,6 +24,7 @@
****************************************************************************/ ****************************************************************************/
#include "vcscommandpage.h" #include "vcscommandpage.h"
#include "vcscommand.h"
#include <coreplugin/iversioncontrol.h> #include <coreplugin/iversioncontrol.h>
#include <coreplugin/vcsmanager.h> #include <coreplugin/vcsmanager.h>
@@ -32,12 +33,18 @@
#include <utils/algorithm.h> #include <utils/algorithm.h>
#include <utils/commandline.h> #include <utils/commandline.h>
#include <utils/outputformatter.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/shellcommand.h> #include <utils/theme/theme.h>
#include <QDir> #include <QAbstractButton>
#include <QApplication>
#include <QDebug> #include <QDebug>
#include <QDir>
#include <QLabel>
#include <QPlainTextEdit>
#include <QTimer> #include <QTimer>
#include <QVBoxLayout>
using namespace Core; using namespace Core;
using namespace ProjectExplorer; using namespace ProjectExplorer;
@@ -61,6 +68,122 @@ static char JOB_ARGUMENTS[] = "arguments";
static char JOB_TIME_OUT[] = "timeoutFactor"; static char JOB_TIME_OUT[] = "timeoutFactor";
static char JOB_ENABLED[] = "enabled"; 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: // VcsCommandPageFactory:
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
@@ -289,8 +412,8 @@ void VcsCommandPage::delayedInitialize()
extraArgs << tmp; extraArgs << tmp;
} }
ShellCommand *command = vc->createInitialCheckoutCommand(repo, FilePath::fromString(base), VcsCommand *command = vc->createInitialCheckoutCommand(repo, FilePath::fromString(base),
name, extraArgs); name, extraArgs);
for (const JobData &job : qAsConst(m_additionalJobs)) { for (const JobData &job : qAsConst(m_additionalJobs)) {
QTC_ASSERT(!job.job.isEmpty(), continue); QTC_ASSERT(!job.job.isEmpty(), continue);

View File

@@ -30,13 +30,24 @@
#include <projectexplorer/jsonwizard/jsonwizardpagefactory.h> #include <projectexplorer/jsonwizard/jsonwizardpagefactory.h>
#include <utils/filepath.h> #include <utils/filepath.h>
#include <utils/shellcommandpage.h> #include <utils/wizardpage.h>
#include <QCoreApplication> #include <QCoreApplication>
namespace Utils { class FilePath; } QT_BEGIN_NAMESPACE
class QPlainTextEdit;
class QLabel;
QT_END_NAMESPACE
namespace Utils {
class FilePath;
class OutputFormatter;
}
namespace VcsBase { namespace VcsBase {
class VcsCommand;
namespace Internal { namespace Internal {
class VcsCommandPageFactory : public ProjectExplorer::JsonWizardPageFactory class VcsCommandPageFactory : public ProjectExplorer::JsonWizardPageFactory
@@ -51,7 +62,44 @@ public:
bool validateData(Utils::Id typeId, const QVariant &data, QString *errorMessage) override; 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 Q_OBJECT