From f9c4889a7fad90334fa6486497e3362efa62dc40 Mon Sep 17 00:00:00 2001
From: Orgad Shaneh <orgad.shaneh@audiocodes.com>
Date: Tue, 13 Aug 2013 08:37:27 +0300
Subject: [PATCH] VCS: Use runVcs for Command

* Removes duplication
* Supports all flags accepted by runVcs
* Supports output while running

Change-Id: Id067791760753184cd2516c23634564880ca5db0
Reviewed-by: Tobias Hunger <tobias.hunger@digia.com>
---
 src/plugins/git/gitclient.cpp         | 21 ++-----
 src/plugins/git/gitclient.h           |  2 -
 src/plugins/vcsbase/command.cpp       | 89 +++++++++------------------
 src/plugins/vcsbase/command.h         |  6 +-
 src/plugins/vcsbase/vcsbaseclient.cpp | 15 +----
 5 files changed, 39 insertions(+), 94 deletions(-)

diff --git a/src/plugins/git/gitclient.cpp b/src/plugins/git/gitclient.cpp
index 17fd2e507d4..c8cd1d88f1e 100644
--- a/src/plugins/git/gitclient.cpp
+++ b/src/plugins/git/gitclient.cpp
@@ -689,7 +689,7 @@ public:
           m_command(command)
     {
         if (parentCommand) {
-            parentCommand->setExpectChanges(true);
+            parentCommand->addFlags(VcsBasePlugin::ExpectRepoChanges);
             connect(parentCommand, SIGNAL(output(QString)), this, SLOT(readStdOut(QString)));
             connect(parentCommand, SIGNAL(errorText(QString)), this, SLOT(readStdErr(QString)));
         }
@@ -1246,16 +1246,6 @@ void GitClient::slotBlameRevisionRequested(const QString &source, QString change
     blame(fi.absolutePath(), QStringList(), fi.fileName(), change, lineNumber);
 }
 
-void GitClient::appendOutput(const QString &text) const
-{
-    outputWindow()->append(text);
-}
-
-void GitClient::appendOutputSilently(const QString &text) const
-{
-    outputWindow()->appendSilently(text);
-}
-
 QTextCodec *GitClient::getSourceCodec(const QString &file) const
 {
     if (QFileInfo(file).isFile())
@@ -2233,15 +2223,13 @@ VcsBase::Command *GitClient::createCommand(const QString &workingDirectory,
     if (editor)
         connect(command, SIGNAL(finished(bool,int,QVariant)), editor, SLOT(commandFinishedGotoLine(bool,int,QVariant)));
     if (useOutputToWindow) {
+        command->addFlags(VcsBasePlugin::ShowStdOutInLogWindow);
         if (editor) // assume that the commands output is the important thing
-            connect(command, SIGNAL(output(QString)), this, SLOT(appendOutputSilently(QString)));
-        else
-            connect(command, SIGNAL(output(QString)), this, SLOT(appendOutput(QString)));
+            command->addFlags(VcsBasePlugin::SilentOutput);
     } else if (editor) {
         connect(command, SIGNAL(output(QString)), editor, SLOT(setPlainTextFiltered(QString)));
     }
 
-    connect(command, SIGNAL(errorText(QString)), outputWindow(), SLOT(appendError(QString)));
     return command;
 }
 
@@ -2257,7 +2245,8 @@ VcsBase::Command *GitClient::executeGit(const QString &workingDirectory,
     VcsBase::Command *command = createCommand(workingDirectory, editor, useOutputToWindow, editorLineNumber);
     command->addJob(arguments, settings()->intValue(GitSettings::timeoutKey));
     command->setUnixTerminalDisabled(false);
-    command->setExpectChanges(expectChanges);
+    if (expectChanges)
+        command->addFlags(VcsBasePlugin::ExpectRepoChanges);
     command->execute();
     return command;
 }
diff --git a/src/plugins/git/gitclient.h b/src/plugins/git/gitclient.h
index bf7b86e9513..5a487b9bd85 100644
--- a/src/plugins/git/gitclient.h
+++ b/src/plugins/git/gitclient.h
@@ -328,8 +328,6 @@ public slots:
 
 private slots:
     void slotBlameRevisionRequested(const QString &source, QString change, int lineNumber);
-    void appendOutput(const QString &text) const;
-    void appendOutputSilently(const QString &text) const;
     void finishSubmoduleUpdate();
     void fetchFinished(const QVariant &cookie);
 
diff --git a/src/plugins/vcsbase/command.cpp b/src/plugins/vcsbase/command.cpp
index ed0291075b9..8e73d1a3181 100644
--- a/src/plugins/vcsbase/command.cpp
+++ b/src/plugins/vcsbase/command.cpp
@@ -28,6 +28,7 @@
 ****************************************************************************/
 
 #include "command.h"
+#include "vcsbaseplugin.h"
 
 #include <coreplugin/icore.h>
 #include <coreplugin/progressmanager/progressmanager.h>
@@ -70,8 +71,9 @@ public:
     QVariant m_cookie;
     bool m_unixTerminalDisabled;
     int m_defaultTimeout;
-    bool m_expectChanges;
+    unsigned m_flags;
     QTextCodec *m_codec;
+    const QString m_sshPasswordPrompt;
 
     QList<Job> m_jobs;
 
@@ -87,8 +89,9 @@ CommandPrivate::CommandPrivate(const QString &binary,
     m_environment(environment),
     m_unixTerminalDisabled(false),
     m_defaultTimeout(10),
-    m_expectChanges(false),
+    m_flags(0),
     m_codec(0),
+    m_sshPasswordPrompt(VcsBasePlugin::sshPrompt()),
     m_lastExecSuccess(false),
     m_lastExecExitCode(-1)
 {
@@ -152,14 +155,14 @@ void Command::setUnixTerminalDisabled(bool e)
     d->m_unixTerminalDisabled = e;
 }
 
-bool Command::expectChanges() const
+unsigned Command::flags() const
 {
-    return d->m_expectChanges;
+    return d->m_flags;
 }
 
-void Command::setExpectChanges(bool e)
+void Command::addFlags(unsigned f)
 {
-    d->m_expectChanges = e;
+    d->m_flags |= f;
 }
 
 void Command::addJob(const QStringList &arguments)
@@ -200,11 +203,6 @@ int Command::lastExecutionExitCode() const
     return d->m_lastExecExitCode;
 }
 
-QString Command::msgTimeout(int seconds)
-{
-    return tr("Error: VCS timed out after %1s.").arg(seconds);
-}
-
 void Command::run()
 {
     // Check that the binary path is not empty
@@ -213,64 +211,35 @@ void Command::run()
         return;
     }
 
-    const unsigned processFlags = unixTerminalDisabled() ?
-                unsigned(Utils::SynchronousProcess::UnixTerminalDisabled) :
-                unsigned(0);
-    const QSharedPointer<QProcess> process = Utils::SynchronousProcess::createProcess(processFlags);
-    if (!workingDirectory().isEmpty())
-        process->setWorkingDirectory(workingDirectory());
-
-    process->setProcessEnvironment(processEnvironment());
-
-    QByteArray stdOut;
-    QByteArray stdErr;
-    QString error;
+    QString stdOut;
+    QString stdErr;
 
     const int count = d->m_jobs.size();
-    int exitCode = -1;
-    bool ok = true;
+    d->m_lastExecExitCode = -1;
+    d->m_lastExecSuccess = true;
     for (int j = 0; j < count; j++) {
-        process->start(binaryPath(), d->m_jobs.at(j).arguments);
-        if (!process->waitForStarted()) {
-            ok = false;
-            error += QString::fromLatin1("Error: \"%1\" could not be started: %2")
-                    .arg(binaryPath(), process->errorString());
-            break;
-        }
-
-        process->closeWriteChannel();
         const int timeOutSeconds = d->m_jobs.at(j).timeout;
-        if (!Utils::SynchronousProcess::readDataFromProcess(*process,
-                                                            timeOutSeconds >= 0 ? timeOutSeconds * 1000 : -1,
-                                                            &stdOut, &stdErr, false)) {
-            Utils::SynchronousProcess::stopProcess(*process);
-            ok = false;
-            error += msgTimeout(timeOutSeconds);
+        Utils::SynchronousProcessResponse resp =
+                VcsBasePlugin::runVcs(d->m_workingDirectory, d->m_binaryPath,
+                                      d->m_jobs.at(j).arguments,
+                                      timeOutSeconds >= 0 ? timeOutSeconds * 1000 : -1,
+                                      d->m_environment, d->m_sshPasswordPrompt,
+                                      d->m_flags, d->m_codec);
+        stdOut += resp.stdOut;
+        stdErr += resp.stdErr;
+        d->m_lastExecExitCode = resp.exitCode;
+        d->m_lastExecSuccess = resp.result == Utils::SynchronousProcessResponse::Finished;
+        if (!d->m_lastExecSuccess)
             break;
-        }
-
-        error += QString::fromLocal8Bit(stdErr);
-        exitCode = process->exitCode();
-    }
-
-    d->m_lastExecSuccess = ok;
-    d->m_lastExecExitCode = exitCode;
-
-    if (ok) {
-        emit output(Utils::SynchronousProcess::normalizeNewlines(
-                        d->m_codec ? d->m_codec->toUnicode(stdOut)
-                                   : QString::fromLocal8Bit(stdOut.constData(), stdOut.size())));
     }
 
-    if (!error.isEmpty())
-        emit errorText(error);
+    emit output(stdOut);
+    if (!stdErr.isEmpty())
+        emit errorText(stdErr);
 
-    emit finished(ok, exitCode, cookie());
-    if (ok) {
+    emit finished(d->m_lastExecSuccess, d->m_lastExecExitCode, cookie());
+    if (d->m_lastExecSuccess)
         emit success(cookie());
-        if (d->m_expectChanges)
-            Core::ICore::vcsManager()->emitRepositoryChanged(d->m_workingDirectory);
-    }
 
     // As it is used asynchronously, we need to delete ourselves
     this->deleteLater();
diff --git a/src/plugins/vcsbase/command.h b/src/plugins/vcsbase/command.h
index a7985c58aea..bfbb05dbb1e 100644
--- a/src/plugins/vcsbase/command.h
+++ b/src/plugins/vcsbase/command.h
@@ -69,10 +69,8 @@ public:
     bool unixTerminalDisabled() const;
     void setUnixTerminalDisabled(bool);
 
-    bool expectChanges() const;
-    void setExpectChanges(bool);
-
-    static QString msgTimeout(int seconds);
+    unsigned flags() const;
+    void addFlags(unsigned f);
 
     const QVariant &cookie() const;
     void setCookie(const QVariant &cookie);
diff --git a/src/plugins/vcsbase/vcsbaseclient.cpp b/src/plugins/vcsbase/vcsbaseclient.cpp
index 9e4f316de92..0b3a4a28e62 100644
--- a/src/plugins/vcsbase/vcsbaseclient.cpp
+++ b/src/plugins/vcsbase/vcsbaseclient.cpp
@@ -596,27 +596,18 @@ Command *VcsBaseClient::createCommand(const QString &workingDirectory,
     if (editor)
         d->bindCommandToEditor(cmd, editor);
     if (mode == VcsWindowOutputBind) {
-        if (editor) { // assume that the commands output is the important thing
-            connect(cmd, SIGNAL(output(QString)),
-                    ::vcsOutputWindow(), SLOT(appendSilently(QString)));
-        } else {
-            connect(cmd, SIGNAL(output(QString)),
-                    ::vcsOutputWindow(), SLOT(append(QString)));
-        }
+        cmd->addFlags(VcsBasePlugin::ShowStdOutInLogWindow);
+        if (editor) // assume that the commands output is the important thing
+            cmd->addFlags(VcsBasePlugin::SilentOutput);
     } else if (editor) {
         connect(cmd, SIGNAL(output(QString)), editor, SLOT(setPlainText(QString)));
     }
 
-    if (::vcsOutputWindow())
-        connect(cmd, SIGNAL(errorText(QString)),
-                ::vcsOutputWindow(), SLOT(appendError(QString)));
     return cmd;
 }
 
 void VcsBaseClient::enqueueJob(Command *cmd, const QStringList &args)
 {
-    const QString binary = QFileInfo(d->m_clientSettings->binaryPath()).baseName();
-    ::vcsOutputWindow()->appendCommand(cmd->workingDirectory(), binary, args);
     cmd->addJob(args);
     cmd->execute();
 }
-- 
GitLab