Commit 9f14b79c authored by Friedemann Kleint's avatar Friedemann Kleint

Add a clone wizard for version control (base classes + git/svn).

Task-number: 244831
parent b799f32b
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** 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.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://www.qtsoftware.com/contact.
**
**************************************************************************/
#include "clonewizard.h"
#include "clonewizardpage.h"
#include "gitplugin.h"
#include "gitclient.h"
#include <vcsbase/checkoutjobs.h>
#include <utils/qtcassert.h>
#include <QtGui/QIcon>
namespace Git {
namespace Internal {
CloneWizard::CloneWizard(QObject *parent) :
VCSBase::BaseCheckoutWizard(parent)
{
}
QIcon CloneWizard::icon() const
{
return QIcon();
}
QString CloneWizard::description() const
{
return tr("Clones a project from a git repository.");
}
QString CloneWizard::name() const
{
return tr("Git Checkout");
}
QWizardPage *CloneWizard::createParameterPage(const QString &path)
{
CloneWizardPage *cwp = new CloneWizardPage;
cwp->setPath(path);
return cwp;
}
QSharedPointer<VCSBase::AbstractCheckoutJob> CloneWizard::createJob(const QWizardPage *parameterPage,
QString *checkoutPath)
{
// Collect parameters for the clone command.
const CloneWizardPage *cwp = qobject_cast<const CloneWizardPage *>(parameterPage);
QTC_ASSERT(cwp, return QSharedPointer<VCSBase::AbstractCheckoutJob>())
const GitClient *client = GitPlugin::instance()->gitClient();
QStringList args = client->binary();
const QString workingDirectory = cwp->path();
const QString directory = cwp->directory();
*checkoutPath = workingDirectory + QLatin1Char('/') + directory;
args << QLatin1String("clone") << cwp->repository() << directory;
const QString binary = args.front();
args.pop_front();
VCSBase::AbstractCheckoutJob *job = new VCSBase::ProcessCheckoutJob(binary, args, workingDirectory,
client->processEnvironment());
return QSharedPointer<VCSBase::AbstractCheckoutJob>(job);
}
} // namespace Internal
} // namespace Git
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** 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.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://www.qtsoftware.com/contact.
**
**************************************************************************/
#ifndef CLONEWIZARD_H
#define CLONEWIZARD_H
#include <vcsbase/basecheckoutwizard.h>
namespace Git {
namespace Internal {
class CloneWizard : public VCSBase::BaseCheckoutWizard
{
public:
explicit CloneWizard(QObject *parent = 0);
// IWizard
virtual QIcon icon() const;
virtual QString description() const;
virtual QString name() const;
protected:
// BaseCheckoutWizard
virtual QWizardPage *createParameterPage(const QString &path);
virtual QSharedPointer<VCSBase::AbstractCheckoutJob> createJob(const QWizardPage *parameterPage,
QString *checkoutPath);
};
} // namespace Internal
} // namespace Git
#endif // CLONEWIZARD_H
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** 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.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://www.qtsoftware.com/contact.
**
**************************************************************************/
#include "clonewizardpage.h"
namespace Git {
namespace Internal {
CloneWizardPage::CloneWizardPage(QWidget *parent) :
VCSBase::BaseCheckoutWizardPage(parent),
m_mainLinePostfix(QLatin1String("/mainline.git")),
m_gitPostFix(QLatin1String(".git")),
m_protocolDelimiter(QLatin1String("://"))
{
setSubTitle(tr("Specify repository URL, checkout directory and path."));
setRepositoryLabel(tr("Clone URL:"));
}
QString CloneWizardPage::directoryFromRepository(const QString &urlIn) const
{
/* Try to figure out a good directory name from something like:
* 'user@host:qt/qt.git', 'http://host/qt/qt.git' 'local repo'
* ------> 'qt' . */
QString url = urlIn.trimmed();
const QChar slash = QLatin1Char('/');
// remove host
const int protocolDelimiterPos = url.indexOf(m_protocolDelimiter); // "://"
const int startRepoSearchPos = protocolDelimiterPos == -1 ? 0 : protocolDelimiterPos + m_protocolDelimiter.size();
int repoPos = url.indexOf(QLatin1Char(':'), startRepoSearchPos);
if (repoPos == -1)
repoPos = url.indexOf(slash, startRepoSearchPos);
if (repoPos != -1)
url.remove(0, repoPos + 1);
// Remove postfixes
if (url.endsWith(m_mainLinePostfix)) {
url.truncate(url.size() - m_mainLinePostfix.size());
} else {
if (url.endsWith(m_gitPostFix)) {
url.truncate(url.size() - m_gitPostFix.size());
}
}
// Check for equal parts, something like "qt/qt" -> "qt"
const int slashPos = url.indexOf(slash);
if (slashPos != -1 && slashPos == (url.size() - 1) / 2) {
if (url.leftRef(slashPos) == url.rightRef(slashPos))
url.truncate(slashPos);
}
// fix invalid characters
const QChar dash = QLatin1Char('-');
url.replace(slash, dash);
url.replace(QLatin1Char('.'), dash);
return url;
}
} // namespace Internal
} // namespace Git
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** 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.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://www.qtsoftware.com/contact.
**
**************************************************************************/
#ifndef CLONEWIZARDPAGE_H
#define CLONEWIZARDPAGE_H
#include <vcsbase/basecheckoutwizardpage.h>
namespace Git {
namespace Internal {
class CloneWizardPage : public VCSBase::BaseCheckoutWizardPage
{
Q_OBJECT
public:
CloneWizardPage(QWidget *parent = 0);
protected:
virtual QString directoryFromRepository(const QString &r) const;
private:
const QString m_mainLinePostfix;
const QString m_gitPostFix;
const QString m_protocolDelimiter;
};
} // namespace Internal
} // namespace Git
#endif // CLONEWIZARDPAGE_H
......@@ -21,7 +21,9 @@ HEADERS += gitplugin.h \
gitsettings.h \
branchdialog.h \
branchmodel.h \
gitcommand.h
gitcommand.h \
clonewizard.h \
clonewizardpage.h
SOURCES += gitplugin.cpp \
gitoutputwindow.cpp \
gitclient.cpp \
......@@ -36,7 +38,9 @@ SOURCES += gitplugin.cpp \
gitsettings.cpp \
branchdialog.cpp \
branchmodel.cpp \
gitcommand.cpp
gitcommand.cpp \
clonewizard.cpp \
clonewizardpage.cpp
FORMS += changeselectiondialog.ui \
settingspage.ui \
gitsubmitpanel.ui \
......
......@@ -480,11 +480,7 @@ GitCommand *GitClient::createCommand(const QString &workingDirectory,
GitOutputWindow *outputWindow = m_plugin->outputWindow();
ProjectExplorer::Environment environment = ProjectExplorer::Environment::systemEnvironment();
if (m_settings.adoptPath)
environment.set(QLatin1String("PATH"), m_settings.path);
GitCommand* command = new GitCommand(m_binaryPath, workingDirectory, environment);
GitCommand* command = new GitCommand(binary(), workingDirectory, processEnvironment());
if (outputToWindow) {
if (!editor) { // assume that the commands output is the important thing
connect(command, SIGNAL(outputData(QByteArray)), this, SLOT(appendDataAndPopup(QByteArray)));
......@@ -527,6 +523,26 @@ void GitClient::appendAndPopup(const QString &text)
m_plugin->outputWindow()->popup(false);
}
// Return fixed arguments required to run
QStringList GitClient::binary() const
{
#ifdef Q_OS_WIN
QStringList args;
args << QLatin1String("cmd.exe") << QLatin1String("/c") << m_binaryPath;
return args;
#else
return QStringList(m_binaryPath);
#endif
}
QStringList GitClient::processEnvironment() const
{
ProjectExplorer::Environment environment = ProjectExplorer::Environment::systemEnvironment();
if (m_settings.adoptPath)
environment.set(QLatin1String("PATH"), m_settings.path);
return environment.toStringList();
}
bool GitClient::synchronousGit(const QString &workingDirectory,
const QStringList &arguments,
QByteArray* outputText,
......@@ -541,19 +557,13 @@ bool GitClient::synchronousGit(const QString &workingDirectory,
QProcess process;
process.setWorkingDirectory(workingDirectory);
process.setEnvironment(processEnvironment());
ProjectExplorer::Environment environment = ProjectExplorer::Environment::systemEnvironment();
if (m_settings.adoptPath)
environment.set(QLatin1String("PATH"), m_settings.path);
process.setEnvironment(environment.toStringList());
#ifdef Q_OS_WIN
QStringList args;
args << "/c" << m_binaryPath << arguments;
process.start(QLatin1String("cmd.exe"), args);
#else
process.start(m_binaryPath, arguments);
#endif
QStringList args = binary();
const QString executable = args.front();
args.pop_front();
args.append(arguments);
process.start(executable, arguments);
process.closeWriteChannel();
if (!process.waitForFinished()) {
......
......@@ -135,6 +135,9 @@ public:
GitSettings settings() const;
void setSettings(const GitSettings &s);
QStringList binary() const; // Executable + basic arguments
QStringList processEnvironment() const;
static QString msgNoChangedFiles();
static const char *noColorOption;
......
......@@ -44,15 +44,6 @@
namespace Git {
namespace Internal {
// Convert environment to list, default to system one.
static inline QStringList environmentToList(const ProjectExplorer::Environment &environment)
{
const QStringList list = environment.toStringList();
if (!list.empty())
return list;
return ProjectExplorer::Environment::systemEnvironment().toStringList();
}
static QString msgTermination(int exitCode, const QString &binaryPath, const QStringList &args)
{
QString cmd = QFileInfo(binaryPath).baseName();
......@@ -71,14 +62,16 @@ GitCommand::Job::Job(const QStringList &a, int t) :
{
}
GitCommand::GitCommand(const QString &binaryPath,
const QString &workingDirectory,
ProjectExplorer::Environment &environment) :
m_binaryPath(binaryPath),
GitCommand::GitCommand(const QStringList &binary,
const QString &workingDirectory,
const QStringList &environment) :
m_binaryPath(binary.front()),
m_basicArguments(binary),
m_workingDirectory(workingDirectory),
m_environment(environmentToList(environment)),
m_environment(environment),
m_reportTerminationMode(NoReport)
{
m_basicArguments.pop_front();
}
GitCommand::TerminationReportMode GitCommand::reportTerminationMode() const
......@@ -132,13 +125,7 @@ void GitCommand::run()
if (Git::Constants::debug)
qDebug() << "GitCommand::run" << j << '/' << count << m_jobs.at(j).arguments;
#ifdef Q_OS_WIN
QStringList args;
args << "/c" << m_binaryPath << m_jobs.at(j).arguments;
process.start(QLatin1String("cmd.exe"), args);
#else
process.start(m_binaryPath, m_jobs.at(j).arguments);
#endif
process.start(m_binaryPath, m_basicArguments + m_jobs.at(j).arguments);
if(!process.waitForStarted()) {
ok = false;
error += QString::fromLatin1("Error: \"%1\" could not be started: %2").arg(m_binaryPath, process.errorString());
......
......@@ -30,9 +30,8 @@
#ifndef GITCOMMAND_H
#define GITCOMMAND_H
#include <projectexplorer/environment.h>
#include <QtCore/QObject>
#include <QtCore/QStringList>
namespace Git {
namespace Internal {
......@@ -47,9 +46,9 @@ public:
ReportStdout, // This assumes UTF8
ReportStderr };
explicit GitCommand(const QString &binaryPath,
explicit GitCommand(const QStringList &binary,
const QString &workingDirectory,
ProjectExplorer::Environment &environment);
const QStringList &environment);
void addJob(const QStringList &arguments, int timeout);
......@@ -79,6 +78,7 @@ private:
};
const QString m_binaryPath;
QStringList m_basicArguments;
const QString m_workingDirectory;
const QStringList m_environment;
......
......@@ -37,6 +37,7 @@
#include "gitsubmiteditor.h"
#include "gitversioncontrol.h"
#include "branchdialog.h"
#include "clonewizard.h"
#include <coreplugin/icore.h>
#include <coreplugin/coreconstants.h>
......@@ -139,10 +140,6 @@ GitPlugin::GitPlugin() :
m_gitClient(0),
m_outputWindow(0),
m_changeSelectionDialog(0),
m_settingsPage(0),
m_coreListener(0),
m_submitEditorFactory(0),
m_versionControl(0),
m_changeTmpFile(0),
m_submitActionTriggered(false)
{
......@@ -151,42 +148,6 @@ GitPlugin::GitPlugin() :
GitPlugin::~GitPlugin()
{
if (m_outputWindow) {
removeObject(m_outputWindow);
delete m_outputWindow;
m_outputWindow = 0;
}
if (m_settingsPage) {
removeObject(m_settingsPage);
delete m_settingsPage;
m_settingsPage = 0;
}
if (!m_editorFactories.empty()) {
foreach (Core::IEditorFactory* pf, m_editorFactories)
removeObject(pf);
qDeleteAll(m_editorFactories);
}
if (m_coreListener) {
removeObject(m_coreListener);
delete m_coreListener;
m_coreListener = 0;
}
if (m_submitEditorFactory) {
removeObject(m_submitEditorFactory);
delete m_submitEditorFactory;
m_submitEditorFactory = 0;
}
if (m_versionControl) {
removeObject(m_versionControl);
delete m_versionControl;
m_versionControl = 0;
}
cleanChangeTmpFile();
delete m_gitClient;
m_instance = 0;
......@@ -231,33 +192,30 @@ bool GitPlugin::initialize(const QStringList &arguments, QString *errorMessage)
m_core = Core::ICore::instance();
m_gitClient = new GitClient(this);
// Create the globalcontext list to register actions accordingly
// Create the globalco6664324b12a3339d18251df1cd69a1da06d1e2dcntext list to register actions accordingly
QList<int> globalcontext;
globalcontext << m_core->uniqueIDManager()->uniqueIdentifier(Core::Constants::C_GLOBAL);
// Create the output Window
m_outputWindow = new GitOutputWindow();
addObject(m_outputWindow);
addAutoReleasedObject(m_outputWindow);
// Create the settings Page
m_settingsPage = new SettingsPage();
addObject(m_settingsPage);
addAutoReleasedObject(new SettingsPage());
static const char *describeSlot = SLOT(show(QString,QString));
const int editorCount = sizeof(editorParameters)/sizeof(VCSBase::VCSBaseEditorParameters);
for (int i = 0; i < editorCount; i++) {
m_editorFactories.push_back(new GitEditorFactory(editorParameters + i, m_gitClient, describeSlot));
addObject(m_editorFactories.back());
}
for (int i = 0; i < editorCount; i++)
addAutoReleasedObject(new GitEditorFactory(editorParameters + i, m_gitClient, describeSlot));
m_coreListener = new CoreListener(this);
addObject(m_coreListener);
addAutoReleasedObject(new CoreListener(this));
m_submitEditorFactory = new GitSubmitEditorFactory(&submitParameters);
addObject(m_submitEditorFactory);
addAutoReleasedObject(new GitSubmitEditorFactory(&submitParameters));
m_versionControl = new GitVersionControl(m_gitClient);
addObject(m_versionControl);
GitVersionControl *versionControl = new GitVersionControl(m_gitClient);
addAutoReleasedObject(versionControl);
addAutoReleasedObject(new CloneWizard);
//register actions
Core::ActionManager *actionManager = m_core->actionManager();
......@@ -270,8 +228,8 @@ bool GitPlugin::initialize(const QStringList &arguments, QString *errorMessage)
gitContainer->menu()->setTitle(tr("&Git"));
toolsContainer->addMenu(gitContainer);
if (QAction *ma = gitContainer->menu()->menuAction()) {
ma->setEnabled(m_versionControl->isEnabled());
connect(m_versionControl, SIGNAL(enabledChanged(bool)), ma, SLOT(setVisible(bool)));
ma->setEnabled(versionControl->isEnabled());
connect(versionControl, SIGNAL(enabledChanged(bool)), ma, SLOT(setVisible(bool)));
}
Core::Command *command;
......@@ -888,4 +846,9 @@ void GitPlugin::setSettings(const GitSettings &s)
m_gitClient->setSettings(s);
}
GitClient *GitPlugin::gitClient() const
{
return m_gitClient;
}
Q_EXPORT_PLUGIN(GitPlugin)
......@@ -96,10 +96,11 @@ public:
GitOutputWindow *outputWindow() const;
GitSettings settings() const;
void setSettings(const GitSettings &s);
GitClient *gitClient() const;
public slots:
void updateActions();
bool editorAboutToClose(Core::IEditor *editor);
......@@ -166,11 +167,6 @@ private:
GitClient *m_gitClient;
GitOutputWindow *m_outputWindow;
ChangeSelectionDialog *m_changeSelectionDialog;
SettingsPage *m_settingsPage;
QList<Core::IEditorFactory*> m_editorFactories;
CoreListener *m_coreListener;
Core::IEditorFactory *m_submitEditorFactory;
Core::IVersionControl *m_versionControl;
QString m_submitRepository;
QStringList m_submitOrigCommitFiles;
QStringList m_submitOrigDeleteFiles;
......
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** 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.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://www.qtsoftware.com/contact.
**
**************************************************************************/
#include "checkoutwizard.h"
#include "checkoutwizardpage.h"
#include "subversionplugin.h"
#include <vcsbase/checkoutjobs.h>
#include <utils/qtcassert.h>
#include <QtGui/QIcon>
namespace Subversion {
namespace Internal {
CheckoutWizard::CheckoutWizard(QObject *parent) :
VCSBase::BaseCheckoutWizard(parent)
{
}
QIcon CheckoutWizard::icon() const
{
return QIcon();
}