Commit aefd6147 authored by Orgad Shaneh's avatar Orgad Shaneh Committed by Orgad Shaneh

VCS: Replace AbstractCheckoutJob with Command

Command now provides the same functionality. Deduplicate code.

Change-Id: I789f021050471281870b6ef6a81a94e66fbdf0c7
Reviewed-by: default avatarTobias Hunger <tobias.hunger@digia.com>
parent 27e53f74
......@@ -35,7 +35,7 @@
#include "bazaarsettings.h"
#include <coreplugin/iversioncontrol.h>
#include <vcsbase/checkoutjobs.h>
#include <vcsbase/command.h>
#include <vcsbase/vcsbaseconstants.h>
#include <vcsbase/vcsconfigurationpage.h>
......@@ -77,13 +77,13 @@ QList<QWizardPage *> CloneWizard::createParameterPages(const QString &path)
return wizardPageList;
}
QSharedPointer<VcsBase::AbstractCheckoutJob> CloneWizard::createJob(const QList<QWizardPage *> &parameterPages,
QString *checkoutPath)
VcsBase::Command *CloneWizard::createCommand(const QList<QWizardPage *> &parameterPages,
QString *checkoutPath)
{
const CloneWizardPage *page = qobject_cast<const CloneWizardPage *>(parameterPages.front());
if (!page)
return QSharedPointer<VcsBase::AbstractCheckoutJob>();
return 0;
const BazaarSettings &settings = BazaarPlugin::instance()->settings();
*checkoutPath = page->path() + QLatin1Char('/') + page->directory();
......@@ -111,7 +111,8 @@ QSharedPointer<VcsBase::AbstractCheckoutJob> CloneWizard::createJob(const QList<
args << client->vcsCommandString(BazaarClient::CloneCommand)
<< extraOptions << page->repository() << page->directory();
VcsBase::ProcessCheckoutJob *job = new VcsBase::ProcessCheckoutJob;
job->addStep(settings.binaryPath(), args, page->path());
return QSharedPointer<VcsBase::AbstractCheckoutJob>(job);
VcsBase::Command *command = new VcsBase::Command(settings.binaryPath(), page->path(),
client->processEnvironment());
command->addJob(args, -1);
return command;
}
......@@ -50,8 +50,8 @@ public:
protected:
QList<QWizardPage *> createParameterPages(const QString &path);
QSharedPointer<VcsBase::AbstractCheckoutJob> createJob(const QList<QWizardPage *> &parameterPages,
QString *checkoutPath);
VcsBase::Command *createCommand(const QList<QWizardPage *> &parameterPages,
QString *checkoutPath);
private:
const QIcon m_icon;
......
......@@ -32,7 +32,7 @@
#include "cvsplugin.h"
#include <coreplugin/iversioncontrol.h>
#include <vcsbase/checkoutjobs.h>
#include <vcsbase/command.h>
#include <vcsbase/vcsbaseconstants.h>
#include <vcsbase/vcsconfigurationpage.h>
#include <utils/qtcassert.h>
......@@ -75,13 +75,13 @@ QList<QWizardPage*> CheckoutWizard::createParameterPages(const QString &path)
return rc;
}
QSharedPointer<VcsBase::AbstractCheckoutJob> CheckoutWizard::createJob(const QList<QWizardPage*> &parameterPages,
QString *checkoutPath)
VcsBase::Command *CheckoutWizard::createCommand(const QList<QWizardPage*> &parameterPages,
QString *checkoutPath)
{
// Collect parameters for the checkout command.
// CVS does not allow for checking out into a different directory.
const CheckoutWizardPage *cwp = qobject_cast<const CheckoutWizardPage *>(parameterPages.front());
QTC_ASSERT(cwp, return QSharedPointer<VcsBase::AbstractCheckoutJob>());
QTC_ASSERT(cwp, return 0);
const CvsSettings settings = CvsPlugin::instance()->settings();
const QString binary = settings.cvsBinaryPath;
QStringList args;
......@@ -90,9 +90,10 @@ QSharedPointer<VcsBase::AbstractCheckoutJob> CheckoutWizard::createJob(const QLi
const QString workingDirectory = cwp->path();
*checkoutPath = workingDirectory + QLatin1Char('/') + repository;
VcsBase::ProcessCheckoutJob *job = new VcsBase::ProcessCheckoutJob;
job->addStep(binary, settings.addOptions(args), workingDirectory);
return QSharedPointer<VcsBase::AbstractCheckoutJob>(job);
VcsBase::Command *command = new VcsBase::Command(binary, workingDirectory,
QProcessEnvironment::systemEnvironment());
command->addJob(settings.addOptions(args), -1);
return command;
}
} // namespace Internal
......
......@@ -49,8 +49,8 @@ public:
protected:
// BaseCheckoutWizard
QList<QWizardPage*> createParameterPages(const QString &path);
QSharedPointer<VcsBase::AbstractCheckoutJob> createJob(const QList<QWizardPage*> &parameterPage,
QString *checkoutPath);
VcsBase::Command *createCommand(const QList<QWizardPage*> &parameterPage,
QString *checkoutPath);
};
} // namespace Internal
......
......@@ -225,6 +225,7 @@ bool CvsPlugin::initialize(const QStringList &arguments, QString *errorMessage)
using namespace Core::Constants;
using namespace ExtensionSystem;
using Core::Command;
initializeVcs(new CvsControl(this));
......
......@@ -33,7 +33,6 @@
#include "gitplugin.h"
#include "gitversioncontrol.h"
#include <vcsbase/checkoutjobs.h>
#include <vcsbase/vcsbaseconstants.h>
#include <vcsbase/vcsconfigurationpage.h>
#include <utils/qtcassert.h>
......@@ -76,8 +75,8 @@ QList<QWizardPage*> CloneWizard::createParameterPages(const QString &path)
return rc;
}
QSharedPointer<VcsBase::AbstractCheckoutJob> CloneWizard::createJob(const QList<QWizardPage*> &parameterPages,
QString *checkoutPath)
VcsBase::Command *CloneWizard::createCommand(const QList<QWizardPage*> &parameterPages,
QString *checkoutPath)
{
// Collect parameters for the clone command.
const CloneWizardPage *cwp = 0;
......@@ -87,7 +86,7 @@ QSharedPointer<VcsBase::AbstractCheckoutJob> CloneWizard::createJob(const QList<
break;
}
QTC_ASSERT(cwp, return QSharedPointer<VcsBase::AbstractCheckoutJob>());
QTC_ASSERT(cwp, return 0);
return cwp->createCheckoutJob(checkoutPath);
}
......
......@@ -49,8 +49,8 @@ public:
protected:
// BaseCheckoutWizard
QList<QWizardPage*> createParameterPages(const QString &path);
QSharedPointer<VcsBase::AbstractCheckoutJob> createJob(const QList<QWizardPage*> &parameterPages,
QString *checkoutPath);
VcsBase::Command *createCommand(const QList<QWizardPage*> &parameterPages,
QString *checkoutPath);
};
} // namespace Internal
......
......@@ -31,7 +31,7 @@
#include "gitplugin.h"
#include "gitclient.h"
#include <vcsbase/checkoutjobs.h>
#include <vcsbase/command.h>
namespace Git {
......@@ -112,25 +112,24 @@ QString CloneWizardPage::directoryFromRepository(const QString &urlIn) const
return url;
}
QSharedPointer<VcsBase::AbstractCheckoutJob> CloneWizardPage::createCheckoutJob(QString *checkoutPath) const
VcsBase::Command *CloneWizardPage::createCheckoutJob(QString *checkoutPath) const
{
const Internal::GitClient *client = Internal::GitPlugin::instance()->gitClient();
const QString workingDirectory = path();
const QString checkoutDir = directory();
*checkoutPath = workingDirectory + QLatin1Char('/') + checkoutDir;
const QString binary = client->gitBinaryPath();
VcsBase::ProcessCheckoutJob *job = new VcsBase::ProcessCheckoutJob;
const QProcessEnvironment env = client->processEnvironment();
const QString checkoutBranch = branch();
QStringList args(QLatin1String("clone"));
if (!checkoutBranch.isEmpty())
args << QLatin1String("--branch") << checkoutBranch;
args << repository() << checkoutDir;
job->addStep(binary, args, workingDirectory, env);
return QSharedPointer<VcsBase::AbstractCheckoutJob>(job);
VcsBase::Command *command = new VcsBase::Command(client->gitBinaryPath(), workingDirectory,
client->processEnvironment());
command->addFlags(VcsBase::VcsBasePlugin::MergeOutputChannels);
command->addJob(args, -1);
return command;
}
QStringList CloneWizardPage::branches(const QString &repository, int *current)
......
......@@ -35,7 +35,7 @@
#include <QSharedPointer>
namespace VcsBase {
class AbstractCheckoutJob;
class Command;
}
namespace Git {
......@@ -50,7 +50,7 @@ public:
explicit CloneWizardPage(QWidget *parent = 0);
~CloneWizardPage();
QSharedPointer<VcsBase::AbstractCheckoutJob> createCheckoutJob(QString *checkoutPath) const;
VcsBase::Command *createCheckoutJob(QString *checkoutPath) const;
protected:
QString directoryFromRepository(const QString &r) const;
......
......@@ -33,7 +33,6 @@
#include "gitsettings.h"
#include <coreplugin/editormanager/ieditor.h>
#include <vcsbase/command.h>
#include <QObject>
#include <QString>
......@@ -52,8 +51,9 @@ namespace Core {
}
namespace VcsBase {
class VcsBaseEditorWidget;
class Command;
class SubmitFileModel;
class VcsBaseEditorWidget;
}
namespace Utils {
......
......@@ -36,7 +36,6 @@
#include "../gitplugin.h"
#include <coreplugin/iversioncontrol.h>
#include <vcsbase/checkoutjobs.h>
#include <vcsbase/vcsbaseconstants.h>
#include <vcsbase/vcsconfigurationpage.h>
#include <utils/qtcassert.h>
......@@ -109,11 +108,11 @@ QList<QWizardPage*> GitoriousCloneWizard::createParameterPages(const QString &pa
return rc;
}
QSharedPointer<VcsBase::AbstractCheckoutJob> GitoriousCloneWizard::createJob(const QList<QWizardPage*> &parameterPages,
QString *checkoutPath)
VcsBase::Command *GitoriousCloneWizard::createCommand(const QList<QWizardPage*> &parameterPages,
QString *checkoutPath)
{
const Git::CloneWizardPage *cwp = qobject_cast<const Git::CloneWizardPage *>(parameterPages.back());
QTC_ASSERT(cwp, return QSharedPointer<VcsBase::AbstractCheckoutJob>());
QTC_ASSERT(cwp, return 0);
return cwp->createCheckoutJob(checkoutPath);
}
......
......@@ -51,8 +51,8 @@ public:
protected:
// BaseCheckoutWizard
QList<QWizardPage*> createParameterPages(const QString &path);
QSharedPointer<VcsBase::AbstractCheckoutJob> createJob(const QList<QWizardPage*> &parameterPages,
QString *checkoutPath);
VcsBase::Command *createCommand(const QList<QWizardPage*> &parameterPages,
QString *checkoutPath);
};
} // namespace Internal
......
......@@ -33,7 +33,7 @@
#include "mercurialsettings.h"
#include <coreplugin/iversioncontrol.h>
#include <vcsbase/checkoutjobs.h>
#include <vcsbase/command.h>
#include <vcsbase/vcsbaseconstants.h>
#include <vcsbase/vcsconfigurationpage.h>
......@@ -74,13 +74,13 @@ QList<QWizardPage *> CloneWizard::createParameterPages(const QString &path)
return wizardPageList;
}
QSharedPointer<AbstractCheckoutJob> CloneWizard::createJob(const QList<QWizardPage *> &parameterPages,
QString *checkoutPath)
Command *CloneWizard::createCommand(const QList<QWizardPage *> &parameterPages,
QString *checkoutPath)
{
const CloneWizardPage *page = qobject_cast<const CloneWizardPage *>(parameterPages.front());
if (!page)
return QSharedPointer<AbstractCheckoutJob>();
return 0;
const MercurialSettings &settings = MercurialPlugin::settings();
......@@ -90,7 +90,8 @@ QSharedPointer<AbstractCheckoutJob> CloneWizard::createJob(const QList<QWizardPa
QStringList args;
args << QLatin1String("clone") << page->repository() << directory;
*checkoutPath = path + QLatin1Char('/') + directory;
ProcessCheckoutJob *job = new ProcessCheckoutJob;
job->addStep(settings.binaryPath(), args, path);
return QSharedPointer<AbstractCheckoutJob>(job);
VcsBase::Command *command = new VcsBase::Command(settings.binaryPath(), path,
QProcessEnvironment::systemEnvironment());
command->addJob(args, -1);
return command;
}
......@@ -49,8 +49,8 @@ public:
protected:
QList<QWizardPage *> createParameterPages(const QString &path);
QSharedPointer<VcsBase::AbstractCheckoutJob> createJob(const QList<QWizardPage *> &parameterPages,
QString *checkoutPath);
VcsBase::Command *createCommand(const QList<QWizardPage *> &parameterPages,
QString *checkoutPath);
private:
const QIcon m_icon;
......
......@@ -32,7 +32,7 @@
#include "subversionplugin.h"
#include <coreplugin/iversioncontrol.h>
#include <vcsbase/checkoutjobs.h>
#include <vcsbase/command.h>
#include <vcsbase/vcsbaseconstants.h>
#include <vcsbase/vcsconfigurationpage.h>
#include <utils/qtcassert.h>
......@@ -75,12 +75,12 @@ QList<QWizardPage*> CheckoutWizard::createParameterPages(const QString &path)
return rc;
}
QSharedPointer<VcsBase::AbstractCheckoutJob> CheckoutWizard::createJob(const QList<QWizardPage*> &parameterPages,
QString *checkoutPath)
VcsBase::Command *CheckoutWizard::createCommand(const QList<QWizardPage*> &parameterPages,
QString *checkoutPath)
{
// Collect parameters for the checkout command.
const CheckoutWizardPage *cwp = qobject_cast<const CheckoutWizardPage *>(parameterPages.front());
QTC_ASSERT(cwp, return QSharedPointer<VcsBase::AbstractCheckoutJob>());
QTC_ASSERT(cwp, return 0);
const SubversionSettings settings = SubversionPlugin::instance()->settings();
const QString binary = settings.binaryPath();
const QString directory = cwp->directory();
......@@ -93,9 +93,10 @@ QSharedPointer<VcsBase::AbstractCheckoutJob> CheckoutWizard::createJob(const QLi
const QString pwd = settings.stringValue(SubversionSettings::passwordKey);
args = SubversionPlugin::addAuthenticationOptions(args, user, pwd);
}
VcsBase::ProcessCheckoutJob *job = new VcsBase::ProcessCheckoutJob;
job->addStep(binary, args, workingDirectory);
return QSharedPointer<VcsBase::AbstractCheckoutJob>(job);
VcsBase::Command *command = new VcsBase::Command(binary, workingDirectory,
QProcessEnvironment::systemEnvironment());
command->addJob(args, -1);
return command;
}
} // namespace Internal
......
......@@ -49,8 +49,8 @@ public:
protected:
// BaseCheckoutWizard
QList<QWizardPage*> createParameterPages(const QString &path);
QSharedPointer<VcsBase::AbstractCheckoutJob> createJob(const QList<QWizardPage*> &parameterPage,
QString *checkoutPath);
VcsBase::Command *createCommand(const QList<QWizardPage*> &parameterPage,
QString *checkoutPath);
};
} // namespace Internal
......
......@@ -29,7 +29,6 @@
#include "basecheckoutwizard.h"
#include "checkoutwizarddialog.h"
#include "checkoutjobs.h"
#include <coreplugin/featureprovider.h>
......@@ -215,8 +214,8 @@ QString BaseCheckoutWizard::openProject(const QString &path, QString *errorMessa
void BaseCheckoutWizard::slotProgressPageShown()
{
const QSharedPointer<AbstractCheckoutJob> job = createJob(d->parameterPages, &(d->checkoutPath));
d->dialog->start(job);
Command *command = createCommand(d->parameterPages, &(d->checkoutPath));
d->dialog->start(command);
}
} // namespace VcsBase
......@@ -45,7 +45,7 @@ namespace Internal {
class BaseCheckoutWizardPrivate;
}
class AbstractCheckoutJob;
class Command;
class VCSBASE_EXPORT BaseCheckoutWizard : public Core::IWizard
{
......@@ -73,8 +73,8 @@ public:
protected:
virtual QList<QWizardPage *> createParameterPages(const QString &path) = 0;
virtual QSharedPointer<AbstractCheckoutJob> createJob(const QList<QWizardPage *> &parameterPages,
QString *checkoutPath) = 0;
virtual Command *createCommand(const QList<QWizardPage *> &parameterPages,
QString *checkoutPath) = 0;
public slots:
void setId(const QString &id);
......
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** 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 Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Digia gives you certain additional
** rights. These rights are described in the Digia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
****************************************************************************/
#include "checkoutjobs.h"
#include "vcsbaseplugin.h"
#include "vcsbaseoutputwindow.h"
#include <QDebug>
#include <QQueue>
#include <QDir>
#include <QStringList>
#include <utils/synchronousprocess.h>
#include <utils/qtcassert.h>
enum { debug = 0 };
/*!
\class VcsBase::AbstractCheckoutJob
\brief The AbstractCheckoutJob class is an abstract base class for a job
creating an initial project checkout.
It should be something that runs in the background producing log messages.
\sa VcsBase::BaseCheckoutWizard
*/
namespace VcsBase {
namespace Internal {
// Use a terminal-less process to suppress SSH prompts.
static inline QSharedPointer<QProcess> createProcess()
{
unsigned flags = 0;
if (VcsBasePlugin::isSshPromptConfigured())
flags = Utils::SynchronousProcess::UnixTerminalDisabled;
return Utils::SynchronousProcess::createProcess(flags);
}
class ProcessCheckoutJobStep
{
public:
ProcessCheckoutJobStep() {}
explicit ProcessCheckoutJobStep(const QString &bin,
const QStringList &args,
const QString &workingDir,
QProcessEnvironment env) :
binary(bin), arguments(args), workingDirectory(workingDir), environment(env) {}
QString binary;
QStringList arguments;
QString workingDirectory;
QProcessEnvironment environment;
};
class ProcessCheckoutJobPrivate
{
public:
ProcessCheckoutJobPrivate();
QSharedPointer<QProcess> process;
QQueue<ProcessCheckoutJobStep> stepQueue;
QString binary;
};
ProcessCheckoutJobPrivate::ProcessCheckoutJobPrivate() :
process(createProcess())
{
}
} // namespace Internal
AbstractCheckoutJob::AbstractCheckoutJob(QObject *parent) :
QObject(parent)
{
}
/*!
\class VcsBase::ProcessCheckoutJob
\brief The ProcessCheckoutJob class is a convenience implementation of a
VcsBase::AbstractCheckoutJob using a QProcess.
*/
ProcessCheckoutJob::ProcessCheckoutJob(QObject *parent) :
AbstractCheckoutJob(parent),
d(new Internal::ProcessCheckoutJobPrivate)
{
connect(d->process.data(), SIGNAL(error(QProcess::ProcessError)), this, SLOT(slotError(QProcess::ProcessError)));
connect(d->process.data(), SIGNAL(finished(int,QProcess::ExitStatus)), this, SLOT(slotFinished(int,QProcess::ExitStatus)));
connect(d->process.data(), SIGNAL(readyReadStandardOutput()), this, SLOT(slotOutput()));
d->process->setProcessChannelMode(QProcess::MergedChannels);
d->process->closeWriteChannel();
}
ProcessCheckoutJob::~ProcessCheckoutJob()
{
delete d;
}
void ProcessCheckoutJob::addStep(const QString &binary,
const QStringList &args,
const QString &workingDirectory,
const QProcessEnvironment &env)
{
if (debug)
qDebug() << "ProcessCheckoutJob::addStep" << binary << args << workingDirectory;
d->stepQueue.enqueue(Internal::ProcessCheckoutJobStep(binary, args, workingDirectory, env));
}
void ProcessCheckoutJob::slotOutput()
{
const QString s = Utils::SynchronousProcess::normalizeNewlines(
QString::fromLocal8Bit(d->process->readAllStandardOutput()));
if (debug)
qDebug() << s;
emit output(s.trimmed());
}
void ProcessCheckoutJob::slotError(QProcess::ProcessError error)
{
switch (error) {
case QProcess::FailedToStart:
emit failed(tr("Unable to start %1: %2").
arg(QDir::toNativeSeparators(d->binary), d->process->errorString()));
break;
default:
emit failed(d->process->errorString());
break;
}
}
void ProcessCheckoutJob::slotFinished (int exitCode, QProcess::ExitStatus exitStatus)
{
if (debug)
qDebug() << "finished" << exitCode << exitStatus;
switch (exitStatus) {
case QProcess::NormalExit:
emit output(tr("The process terminated with exit code %1.").arg(exitCode));
if (exitCode == 0)
slotNext();
else
emit failed(tr("The process returned exit code %1.").arg(exitCode));
break;
case QProcess::CrashExit:
emit failed(tr("The process terminated in an abnormal way."));
break;
}
}
void ProcessCheckoutJob::start()
{
QTC_ASSERT(!d->stepQueue.empty(), return);
slotNext();
}
void ProcessCheckoutJob::slotNext()
{
if (d->stepQueue.isEmpty()) {
emit succeeded();
return;
}
// Launch next
const Internal::ProcessCheckoutJobStep step = d->stepQueue.dequeue();
d->process->setWorkingDirectory(step.workingDirectory);
// Set up SSH correctly.
QProcessEnvironment processEnv = step.environment;
VcsBasePlugin::setProcessEnvironment(&processEnv, false);
d->process->setProcessEnvironment(processEnv);
d->binary = step.binary;
emit output(VcsBaseOutputWindow::msgExecutionLogEntry(step.workingDirectory, d->binary, step.arguments));
d->process->start(d->binary, step.arguments);
}
void ProcessCheckoutJob::cancel()
{
if (debug)
qDebug() << "ProcessCheckoutJob::start";
emit output(tr("Stopping..."));
Utils::SynchronousProcess::stopProcess(*d->process);
}
} // namespace VcsBase
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of Qt Creator.