From 75f067550f15fe384f2b59989a90dcb7dd8d5e43 Mon Sep 17 00:00:00 2001
From: Tobias Hunger <tobias.hunger@theqtcompany.com>
Date: Wed, 29 Apr 2015 14:34:07 +0200
Subject: [PATCH] IVersionControl: Add method to get a ShellCommand for initial
 checkouts

Change-Id: Iabc056dad186d788003b221afb34303c37fef728
Reviewed-by: Orgad Shaneh <orgads@gmail.com>
---
 src/plugins/bazaar/bazaarclient.h             |  2 ++
 src/plugins/bazaar/bazaarcontrol.cpp          | 19 ++++++++++++++++
 src/plugins/bazaar/bazaarcontrol.h            |  5 +++++
 src/plugins/clearcase/clearcasecontrol.cpp    |  1 +
 src/plugins/coreplugin/iversioncontrol.cpp    | 12 ++++++++++
 src/plugins/coreplugin/iversioncontrol.h      | 18 ++++++++++++++-
 src/plugins/cvs/cvscontrol.cpp                | 21 ++++++++++++++++++
 src/plugins/cvs/cvscontrol.h                  |  5 +++++
 src/plugins/git/gitversioncontrol.cpp         | 22 +++++++++++++++----
 src/plugins/git/gitversioncontrol.h           |  5 +++++
 src/plugins/mercurial/mercurialcontrol.cpp    | 16 ++++++++++++++
 src/plugins/mercurial/mercurialcontrol.h      |  5 +++++
 .../perforce/perforceversioncontrol.cpp       |  1 +
 src/plugins/subversion/subversioncontrol.cpp  | 21 ++++++++++++++++++
 src/plugins/subversion/subversioncontrol.h    |  5 +++++
 15 files changed, 153 insertions(+), 5 deletions(-)

diff --git a/src/plugins/bazaar/bazaarclient.h b/src/plugins/bazaar/bazaarclient.h
index 913f3415409..42005bd1662 100644
--- a/src/plugins/bazaar/bazaarclient.h
+++ b/src/plugins/bazaar/bazaarclient.h
@@ -38,6 +38,7 @@ namespace Bazaar {
 namespace Internal {
 
 class BazaarSettings;
+class BazaarControl;
 
 class BazaarClient : public VcsBase::VcsBaseClient
 {
@@ -70,6 +71,7 @@ protected:
 
 private:
     friend class CloneWizard;
+    friend class BazaarControl;
 };
 
 } // namespace Internal
diff --git a/src/plugins/bazaar/bazaarcontrol.cpp b/src/plugins/bazaar/bazaarcontrol.cpp
index e9a9be117dc..5827a9cd603 100644
--- a/src/plugins/bazaar/bazaarcontrol.cpp
+++ b/src/plugins/bazaar/bazaarcontrol.cpp
@@ -29,8 +29,11 @@
 ****************************************************************************/
 #include "bazaarcontrol.h"
 #include "bazaarclient.h"
+#include "bazaarplugin.h"
 
+#include <vcsbase/vcsbaseclientsettings.h>
 #include <vcsbase/vcsbaseconstants.h>
+#include <vcsbase/vcscommand.h>
 
 #include <utils/fileutils.h>
 
@@ -88,6 +91,7 @@ bool BazaarControl::supportsOperation(Operation operation) const
     case Core::IVersionControl::MoveOperation:
     case Core::IVersionControl::CreateRepositoryOperation:
     case Core::IVersionControl::AnnotateOperation:
+    case Core::IVersionControl::InitialCheckoutOperation:
         break;
     case Core::IVersionControl::SnapshotOperations:
         supported = false;
@@ -135,6 +139,21 @@ bool BazaarControl::vcsAnnotate(const QString &file, int line)
     return true;
 }
 
+Core::ShellCommand *BazaarControl::createInitialCheckoutCommand(const QString &url,
+                                                                const Utils::FileName &baseDirectory,
+                                                                const QString &localName,
+                                                                const QStringList &extraArgs)
+{
+    QStringList args;
+    args << m_bazaarClient->vcsCommandString(BazaarClient::CloneCommand)
+         << extraArgs << url << localName;
+
+    auto command = new VcsBase::VcsCommand(baseDirectory.toString(),
+                                           m_bazaarClient->processEnvironment());
+    command->addJob(m_bazaarClient->vcsBinary(), args, -1);
+    return command;
+}
+
 void BazaarControl::changed(const QVariant &v)
 {
     switch (v.type()) {
diff --git a/src/plugins/bazaar/bazaarcontrol.h b/src/plugins/bazaar/bazaarcontrol.h
index bd74926d419..f55ad73ca39 100644
--- a/src/plugins/bazaar/bazaarcontrol.h
+++ b/src/plugins/bazaar/bazaarcontrol.h
@@ -64,6 +64,11 @@ public:
     bool vcsCreateRepository(const QString &directory) override;
     bool vcsAnnotate(const QString &file, int line) override;
 
+    Core::ShellCommand *createInitialCheckoutCommand(const QString &url,
+                                                     const Utils::FileName &baseDirectory,
+                                                     const QString &localName,
+                                                     const QStringList &extraArgs) override;
+
 public slots:
     // To be connected to the VCSTask's success signal to emit the repository/
     // files changed signals according to the variant's type:
diff --git a/src/plugins/clearcase/clearcasecontrol.cpp b/src/plugins/clearcase/clearcasecontrol.cpp
index 686f782a92d..472d79a81b7 100644
--- a/src/plugins/clearcase/clearcasecontrol.cpp
+++ b/src/plugins/clearcase/clearcasecontrol.cpp
@@ -80,6 +80,7 @@ bool ClearCaseControl::supportsOperation(Operation operation) const
         break;
     case CreateRepositoryOperation:
     case SnapshotOperations:
+    case Core::IVersionControl::InitialCheckoutOperation:
         rc = false;
         break;
     }
diff --git a/src/plugins/coreplugin/iversioncontrol.cpp b/src/plugins/coreplugin/iversioncontrol.cpp
index f9cbf4a90d1..d7af51eabbd 100644
--- a/src/plugins/coreplugin/iversioncontrol.cpp
+++ b/src/plugins/coreplugin/iversioncontrol.cpp
@@ -83,6 +83,18 @@ QStringList IVersionControl::additionalToolsPath() const
     return QStringList();
 }
 
+ShellCommand *IVersionControl::createInitialCheckoutCommand(const QString &url,
+                                                            const Utils::FileName &baseDirectory,
+                                                            const QString &localName,
+                                                            const QStringList &extraArgs)
+{
+    Q_UNUSED(url);
+    Q_UNUSED(baseDirectory);
+    Q_UNUSED(localName);
+    Q_UNUSED(extraArgs);
+    return 0;
+}
+
 QString IVersionControl::vcsTopic(const QString &topLevel)
 {
     return m_topicCache ? m_topicCache->topic(topLevel) : QString();
diff --git a/src/plugins/coreplugin/iversioncontrol.h b/src/plugins/coreplugin/iversioncontrol.h
index f9a9d2b76e3..04c733cefd1 100644
--- a/src/plugins/coreplugin/iversioncontrol.h
+++ b/src/plugins/coreplugin/iversioncontrol.h
@@ -34,6 +34,8 @@
 #include "core_global.h"
 #include "id.h"
 
+#include <utils/fileutils.h>
+
 #include <QDateTime>
 #include <QFlags>
 #include <QHash>
@@ -42,6 +44,8 @@
 
 namespace Core {
 
+class ShellCommand;
+
 class CORE_EXPORT IVersionControl : public QObject
 {
     Q_OBJECT
@@ -56,7 +60,8 @@ public:
         AddOperation, DeleteOperation, MoveOperation,
         CreateRepositoryOperation,
         SnapshotOperations,
-        AnnotateOperation
+        AnnotateOperation,
+        InitialCheckoutOperation
     };
 
     enum OpenSupportMode {
@@ -194,6 +199,17 @@ public:
      */
     virtual QStringList additionalToolsPath() const;
 
+    /*!
+     * Return a ShellCommand capable of checking out \a url into \a baseDirectory, where
+     * a new subdirectory with \a localName will be created.
+     *
+     * \a extraArgs are passed on to the command being run.
+     */
+    virtual ShellCommand *createInitialCheckoutCommand(const QString &url,
+                                                       const Utils::FileName &baseDirectory,
+                                                       const QString &localName,
+                                                       const QStringList &extraArgs);
+
 signals:
     void repositoryChanged(const QString &repository);
     void filesChanged(const QStringList &files);
diff --git a/src/plugins/cvs/cvscontrol.cpp b/src/plugins/cvs/cvscontrol.cpp
index ceb1eeca664..82e09bc38aa 100644
--- a/src/plugins/cvs/cvscontrol.cpp
+++ b/src/plugins/cvs/cvscontrol.cpp
@@ -35,8 +35,10 @@
 #include "cvssettings.h"
 
 #include <vcsbase/vcsbaseconstants.h>
+#include <vcsbase/vcscommand.h>
 
 #include <utils/fileutils.h>
+#include <utils/qtcassert.h>
 
 #include <QFileInfo>
 
@@ -74,6 +76,7 @@ bool CvsControl::supportsOperation(Operation operation) const
     case AddOperation:
     case DeleteOperation:
     case AnnotateOperation:
+    case InitialCheckoutOperation:
         break;
     case MoveOperation:
     case CreateRepositoryOperation:
@@ -132,6 +135,24 @@ QString CvsControl::vcsOpenText() const
     return tr("&Edit");
 }
 
+Core::ShellCommand *CvsControl::createInitialCheckoutCommand(const QString &url,
+                                                             const Utils::FileName &baseDirectory,
+                                                             const QString &localName,
+                                                             const QStringList &extraArgs)
+{
+    QTC_ASSERT(localName == url, return 0);
+
+    const CvsSettings settings = CvsPlugin::instance()->client()->settings();
+
+    QStringList args;
+    args << QLatin1String("checkout") << url << extraArgs;
+
+    auto command = new VcsBase::VcsCommand(baseDirectory.toString(),
+                                           QProcessEnvironment::systemEnvironment());
+    command->addJob(m_plugin->client()->vcsBinary(), settings.addOptions(args), -1);
+    return command;
+}
+
 bool CvsControl::managesDirectory(const QString &directory, QString *topLevel) const
 {
     return m_plugin->managesDirectory(directory, topLevel);
diff --git a/src/plugins/cvs/cvscontrol.h b/src/plugins/cvs/cvscontrol.h
index 7d2425aaadf..ec18756877a 100644
--- a/src/plugins/cvs/cvscontrol.h
+++ b/src/plugins/cvs/cvscontrol.h
@@ -63,6 +63,11 @@ public:
 
     QString vcsOpenText() const override;
 
+    Core::ShellCommand *createInitialCheckoutCommand(const QString &url,
+                                                     const Utils::FileName &baseDirectory,
+                                                     const QString &localName,
+                                                     const QStringList &extraArgs) override;
+
     void emitRepositoryChanged(const QString &s);
     void emitFilesChanged(const QStringList &l);
 
diff --git a/src/plugins/git/gitversioncontrol.cpp b/src/plugins/git/gitversioncontrol.cpp
index ba9ec5589e2..bb5f7024e9c 100644
--- a/src/plugins/git/gitversioncontrol.cpp
+++ b/src/plugins/git/gitversioncontrol.cpp
@@ -33,8 +33,10 @@
 #include "gitutils.h"
 
 #include <vcsbase/vcsbaseconstants.h>
+#include <vcsbase/vcscommand.h>
 
 #include <QFileInfo>
+#include <QProcessEnvironment>
 
 namespace Git {
 namespace Internal {
@@ -44,8 +46,7 @@ class GitTopicCache : public Core::IVersionControl::TopicCache
 public:
     GitTopicCache(GitClient *client) :
         m_client(client)
-    {
-    }
+    { }
 
 protected:
     QString trackFile(const QString &repository) override
@@ -66,8 +67,7 @@ private:
 GitVersionControl::GitVersionControl(GitClient *client) :
     Core::IVersionControl(new GitTopicCache(client)),
     m_client(client)
-{
-}
+{ }
 
 QString GitVersionControl::displayName() const
 {
@@ -96,6 +96,7 @@ bool GitVersionControl::supportsOperation(Operation operation) const
     case CreateRepositoryOperation:
     case SnapshotOperations:
     case AnnotateOperation:
+    case InitialCheckoutOperation:
         return true;
     }
     return false;
@@ -139,6 +140,19 @@ QString GitVersionControl::vcsTopic(const QString &directory)
     return topic;
 }
 
+Core::ShellCommand *GitVersionControl::createInitialCheckoutCommand(const QString &url,
+                                                                    const Utils::FileName &baseDirectory,
+                                                                    const QString &localName,
+                                                                    const QStringList &extraArgs)
+{
+    QStringList args;
+    args << QLatin1String("clone") << extraArgs << url << localName;
+
+    auto command = new VcsBase::VcsCommand(baseDirectory.toString(), m_client->processEnvironment());
+    command->addJob(m_client->vcsBinary(), args, -1);
+    return command;
+}
+
 QStringList GitVersionControl::additionalToolsPath() const
 {
     QStringList res = m_client->settings().searchPathList();
diff --git a/src/plugins/git/gitversioncontrol.h b/src/plugins/git/gitversioncontrol.h
index 2e528ab4873..71dedb09ee3 100644
--- a/src/plugins/git/gitversioncontrol.h
+++ b/src/plugins/git/gitversioncontrol.h
@@ -62,6 +62,11 @@ public:
     bool vcsAnnotate(const QString &file, int line) override;
     QString vcsTopic(const QString &directory) override;
 
+    Core::ShellCommand *createInitialCheckoutCommand(const QString &url,
+                                                     const Utils::FileName &baseDirectory,
+                                                     const QString &localName,
+                                                     const QStringList &extraArgs) override;
+
     QStringList additionalToolsPath() const override;
 
     void emitFilesChanged(const QStringList &);
diff --git a/src/plugins/mercurial/mercurialcontrol.cpp b/src/plugins/mercurial/mercurialcontrol.cpp
index 6f5ad95fb16..827355601ff 100644
--- a/src/plugins/mercurial/mercurialcontrol.cpp
+++ b/src/plugins/mercurial/mercurialcontrol.cpp
@@ -33,12 +33,14 @@
 
 #include <vcsbase/vcsbaseclientsettings.h>
 #include <vcsbase/vcsbaseconstants.h>
+#include <vcsbase/vcscommand.h>
 
 #include <coreplugin/vcsmanager.h>
 
 #include <utils/fileutils.h>
 
 #include <QFileInfo>
+#include <QProcessEnvironment>
 #include <QVariant>
 #include <QStringList>
 #include <QDir>
@@ -114,6 +116,7 @@ bool MercurialControl::supportsOperation(Operation operation) const
     case Core::IVersionControl::MoveOperation:
     case Core::IVersionControl::CreateRepositoryOperation:
     case Core::IVersionControl::AnnotateOperation:
+    case Core::IVersionControl::InitialCheckoutOperation:
         break;
     case Core::IVersionControl::SnapshotOperations:
         supported = false;
@@ -161,6 +164,19 @@ bool MercurialControl::vcsAnnotate(const QString &file, int line)
     return true;
 }
 
+Core::ShellCommand *MercurialControl::createInitialCheckoutCommand(const QString &url,
+                                                                   const Utils::FileName &baseDirectory,
+                                                                   const QString &localName,
+                                                                   const QStringList &extraArgs)
+{
+    QStringList args;
+    args << QLatin1String("clone") << extraArgs << url << localName;
+    auto command = new VcsBase::VcsCommand(baseDirectory.toString(),
+                                           mercurialClient->processEnvironment());
+    command->addJob(mercurialClient->vcsBinary(), args, -1);
+    return command;
+}
+
 bool MercurialControl::sccManaged(const QString &filename)
 {
     const QFileInfo fi(filename);
diff --git a/src/plugins/mercurial/mercurialcontrol.h b/src/plugins/mercurial/mercurialcontrol.h
index 6807e57abab..30b33c8de3a 100644
--- a/src/plugins/mercurial/mercurialcontrol.h
+++ b/src/plugins/mercurial/mercurialcontrol.h
@@ -64,6 +64,11 @@ public:
     bool vcsCreateRepository(const QString &directory) override;
     bool vcsAnnotate(const QString &file, int line) override;
 
+    Core::ShellCommand *createInitialCheckoutCommand(const QString &url,
+                                                     const Utils::FileName &baseDirectory,
+                                                     const QString &localName,
+                                                     const QStringList &extraArgs) override;
+
     bool sccManaged(const QString &filename);
 
 public slots:
diff --git a/src/plugins/perforce/perforceversioncontrol.cpp b/src/plugins/perforce/perforceversioncontrol.cpp
index 8ae4b02c069..5e7cb29bb05 100644
--- a/src/plugins/perforce/perforceversioncontrol.cpp
+++ b/src/plugins/perforce/perforceversioncontrol.cpp
@@ -76,6 +76,7 @@ bool PerforceVersionControl::supportsOperation(Operation operation) const
         return supported;
     case CreateRepositoryOperation:
     case SnapshotOperations:
+    case InitialCheckoutOperation:
         break;
     }
     return false;
diff --git a/src/plugins/subversion/subversioncontrol.cpp b/src/plugins/subversion/subversioncontrol.cpp
index a6fe4d48d49..90175620215 100644
--- a/src/plugins/subversion/subversioncontrol.cpp
+++ b/src/plugins/subversion/subversioncontrol.cpp
@@ -31,10 +31,12 @@
 #include "subversioncontrol.h"
 
 #include "subversionclient.h"
+#include "subversionconstants.h"
 #include "subversionplugin.h"
 #include "subversionsettings.h"
 
 #include <vcsbase/vcsbaseconstants.h>
+#include <vcsbase/vcsbaseclientsettings.h>
 
 #include <utils/fileutils.h>
 
@@ -97,6 +99,7 @@ bool SubversionControl::supportsOperation(Operation operation) const
     case DeleteOperation:
     case MoveOperation:
     case AnnotateOperation:
+    case InitialCheckoutOperation:
         break;
     case CreateRepositoryOperation:
     case SnapshotOperations:
@@ -153,6 +156,24 @@ bool SubversionControl::vcsAnnotate(const QString &file, int line)
     return true;
 }
 
+Core::ShellCommand *SubversionControl::createInitialCheckoutCommand(const QString &url,
+                                                                    const Utils::FileName &baseDirectory,
+                                                                    const QString &localName,
+                                                                    const QStringList &extraArgs)
+{
+    SubversionClient *client = m_plugin->client();
+
+    QStringList args;
+    args << QLatin1String("checkout");
+    args << SubversionClient::addAuthenticationOptions(client->settings());
+    args << QLatin1String(Subversion::Constants::NON_INTERACTIVE_OPTION);
+    args << extraArgs << url << localName;
+
+    auto command = new VcsBase::VcsCommand(baseDirectory.toString(), client->processEnvironment());
+    command->addJob(client->vcsBinary(), args, -1);
+    return command;
+}
+
 void SubversionControl::emitRepositoryChanged(const QString &s)
 {
     emit repositoryChanged(s);
diff --git a/src/plugins/subversion/subversioncontrol.h b/src/plugins/subversion/subversioncontrol.h
index 62d2ee902f6..f05185ac1ed 100644
--- a/src/plugins/subversion/subversioncontrol.h
+++ b/src/plugins/subversion/subversioncontrol.h
@@ -60,6 +60,11 @@ public:
 
     bool vcsAnnotate(const QString &file, int line) override;
 
+    Core::ShellCommand *createInitialCheckoutCommand(const QString &url,
+                                                     const Utils::FileName &baseDirectory,
+                                                     const QString &localName,
+                                                     const QStringList &extraArgs) override;
+
     void emitRepositoryChanged(const QString &);
     void emitFilesChanged(const QStringList &);
 
-- 
GitLab