Commit 65e95c3a authored by Tuomas Puranen's avatar Tuomas Puranen Committed by Tobias Hunger
Browse files

Added few new functions to IVersionControl, VCSManager and GeneratedFile to...


Added few new functions to IVersionControl, VCSManager and GeneratedFile to support the funcationality needed by the trac plugin.
All the version control plugins updated to have implementations according to the interface changes.

Merge-request: 2178
Reviewed-by: default avatarTobias Hunger <tobias.hunger@nokia.com>

Merge-request: 2178
Reviewed-by: default avatarTobias Hunger <tobias.hunger@nokia.com>
parent 32fff3f6
......@@ -69,12 +69,14 @@ public:
QString editorId;
bool binary;
GeneratedFile::Attributes attributes;
bool writeAccess;
};
GeneratedFilePrivate::GeneratedFilePrivate(const QString &p) :
path(p),
binary(false),
attributes(0)
attributes(0),
writeAccess(true)
{
}
......@@ -104,6 +106,11 @@ GeneratedFile::~GeneratedFile()
{
}
void GeneratedFile::writeAccess(bool access)
{
m_d->writeAccess = access;
}
QString GeneratedFile::path() const
{
return m_d->path;
......@@ -156,6 +163,9 @@ void GeneratedFile::setEditorId(const QString &k)
bool GeneratedFile::write(QString *errorMessage) const
{
if (!m_d->writeAccess)
return true;
// Ensure the directory
const QFileInfo info(m_d->path);
const QDir dir = info.absoluteDir();
......
......@@ -101,6 +101,7 @@ public:
void setEditorId(const QString &k);
bool write(QString *errorMessage) const;
void writeAccess(bool access = true);
Attributes attributes() const;
void setAttributes(Attributes a);
......
......@@ -52,7 +52,9 @@ public:
AddOperation, DeleteOperation, OpenOperation, MoveOperation,
CreateRepositoryOperation,
SnapshotOperations,
AnnotateOperation
AnnotateOperation,
CheckoutOperation,
GetRepositoryRootOperation
};
explicit IVersionControl(QObject *parent = 0) : QObject(parent) {}
......@@ -116,6 +118,16 @@ public:
*/
virtual bool vcsCreateRepository(const QString &directory) = 0;
/*!
* Called to clone/checkout the version control system in a directory.
*/
virtual bool vcsCheckout(const QString &directory,const QByteArray &url) = 0;
/*!
* Called to get the version control repository root.
*/
virtual QString vcsGetRepositoryURL(const QString &director) = 0;
/*!
* Create a snapshot of the current state and return an identifier or
* an empty string in case of failure.
......
......@@ -167,6 +167,42 @@ bool VCSManager::promptToDelete(const QString &fileName)
return true;
}
IVersionControl* VCSManager::checkout(const QString &versionControlType,
const QString &directory,
const QByteArray &url)
{
foreach (IVersionControl * versionControl, allVersionControls()) {
if (versionControl->displayName() == versionControlType &&
versionControl->supportsOperation(Core::IVersionControl::CheckoutOperation)) {
if (versionControl->vcsCheckout(directory,url)) {
m_d->m_cachedMatches.insert(directory, versionControl);
return versionControl;
}
return 0;
}
}
return 0;
}
bool VCSManager::findVersionControl(const QString &versionControlType)
{
foreach (IVersionControl * versionControl, allVersionControls()) {
if (versionControl->displayName() == versionControlType) {
return true;
}
}
return false;
}
QString VCSManager::getRepositoryURL(const QString &directory)
{
IVersionControl *vc = findVersionControlForDirectory(directory);
if (vc && vc->supportsOperation(Core::IVersionControl::GetRepositoryRootOperation))
return vc->vcsGetRepositoryURL(directory);
return QString();
}
bool VCSManager::promptToDelete(IVersionControl *vc, const QString &fileName)
{
QTC_ASSERT(vc, return true)
......
......@@ -68,6 +68,11 @@ public:
IVersionControl *findVersionControlForDirectory(const QString &directory,
QString *topLevelDirectory = 0);
IVersionControl *checkout(const QString &versionControlType,
const QString &directory,
const QByteArray &url);
bool findVersionControl(const QString &versionControl);
QString getRepositoryURL(const QString &directory);
// Shows a confirmation dialog, whether the file should also be deleted
// from revision control Calls sccDelete on the file. Returns false
......
......@@ -58,6 +58,8 @@ bool CVSControl::supportsOperation(Operation operation) const
case MoveOperation:
case CreateRepositoryOperation:
case SnapshotOperations:
case CheckoutOperation:
case GetRepositoryRootOperation:
rc = false;
break;
}
......@@ -94,6 +96,16 @@ bool CVSControl::vcsCreateRepository(const QString &)
return false;
}
QString CVSControl::vcsGetRepositoryURL(const QString &)
{
return QString();
}
bool CVSControl::vcsCheckout(const QString &/*directory*/, const QByteArray &/*url*/)
{
return false;
}
QString CVSControl::vcsCreateSnapshot(const QString &)
{
return QString();
......
......@@ -53,6 +53,8 @@ public:
virtual bool vcsDelete(const QString &filename);
virtual bool vcsMove(const QString &from, const QString &to);
virtual bool vcsCreateRepository(const QString &directory);
virtual bool vcsCheckout(const QString &directory, const QByteArray &url);
virtual QString vcsGetRepositoryURL(const QString &directory);
virtual QString vcsCreateSnapshot(const QString &topLevel);
virtual QStringList vcsSnapshots(const QString &topLevel);
virtual bool vcsRestoreSnapshot(const QString &topLevel, const QString &name);
......
......@@ -50,6 +50,7 @@
#include <texteditor/itexteditor.h>
#include <utils/qtcassert.h>
#include <utils/synchronousprocess.h>
#include <utils/environment.h>
#include <vcsbase/vcsbaseeditor.h>
#include <vcsbase/vcsbaseoutputwindow.h>
#include <vcsbase/vcsbaseplugin.h>
......@@ -1922,6 +1923,61 @@ QString GitClient::readConfigValue(const QString &workingDirectory, const QStrin
return readConfig(workingDirectory, QStringList(configVar)).remove(QLatin1Char('\n'));
}
bool GitClient::cloneRepository(const QString &directory,const QByteArray &url)
{
QDir workingDirectory(directory);
const unsigned flags = VCSBase::VCSBasePlugin::SshPasswordPrompt
|VCSBase::VCSBasePlugin::ShowStdOutInLogWindow
|VCSBase::VCSBasePlugin::ShowSuccessMessage;
if (workingDirectory.exists()) {
if (!synchronousInit(workingDirectory.path()))
return false;
QStringList arguments(QLatin1String("remote"));
arguments << QLatin1String("add") << QLatin1String("origin") << url;
if (!fullySynchronousGit(workingDirectory.path(),arguments,0,0,true))
return false;
arguments.clear();
arguments << QLatin1String("fetch");
const Utils::SynchronousProcessResponse resp = synchronousGit(workingDirectory.path(),arguments,flags);
if (resp.result != Utils::SynchronousProcessResponse::Finished)
return false;
arguments.clear();
arguments << QLatin1String("config") << QLatin1String("branch.master.remote") << QLatin1String("origin");
if (!fullySynchronousGit(workingDirectory.path(),arguments,0,0,true))
return false;
arguments.clear();
arguments << QLatin1String("config") << QLatin1String("branch.master.merge") << QLatin1String("refs/heads/master");
if (!fullySynchronousGit(workingDirectory.path(),arguments,0,0,true))
return false;
return true;
} else {
QStringList arguments(QLatin1String("clone"));
arguments << url << workingDirectory.dirName();
workingDirectory.cdUp();
const Utils::SynchronousProcessResponse resp = synchronousGit(workingDirectory.path(),arguments,flags);
return resp.result == Utils::SynchronousProcessResponse::Finished;
}
}
QString GitClient::vcsGetRepositoryURL(const QString &directory)
{
QStringList arguments(QLatin1String("config"));
QByteArray outputText;
arguments << QLatin1String("remote.origin.url");
if (fullySynchronousGit(directory,arguments,&outputText,0,false)) {
return commandOutputFromLocal8Bit(outputText);
}
return QString();
}
GitSettings GitClient::settings() const
{
return m_settings;
......
......@@ -158,6 +158,8 @@ public:
unsigned gitVersion(bool silent, QString *errorMessage = 0);
QString gitVersionString(bool silent, QString *errorMessage = 0);
bool cloneRepository(const QString &directory,const QByteArray &url);
QString vcsGetRepositoryURL(const QString &directory);
bool synchronousFetch(const QString &workingDirectory);
bool synchronousPull(const QString &workingDirectory);
bool synchronousPush(const QString &workingDirectory);
......
......@@ -87,6 +87,10 @@ bool GitVersionControl::supportsOperation(Operation operation) const
case AnnotateOperation:
rc = true;
break;
case CheckoutOperation:
case GetRepositoryRootOperation:
rc = true;
break;
}
return rc;
}
......@@ -121,6 +125,17 @@ bool GitVersionControl::vcsCreateRepository(const QString &directory)
{
return gitClient()->synchronousInit(directory);
}
bool GitVersionControl::vcsCheckout(const QString &directory,const QByteArray &url)
{
return gitClient()->cloneRepository(directory,url);
}
QString GitVersionControl::vcsGetRepositoryURL(const QString &directory)
{
return gitClient()->vcsGetRepositoryURL(directory);
}
/* Snapshots are implement using stashes, relying on stash messages for
* naming as the actual stash names (stash{n}) are rotated as one adds stashes.
* Note that the snapshot interface does not care whether we have an unmodified
......
......@@ -54,6 +54,8 @@ public:
virtual bool vcsDelete(const QString &filename);
virtual bool vcsMove(const QString &from, const QString &to);
virtual bool vcsCreateRepository(const QString &directory);
virtual bool vcsCheckout(const QString &directory, const QByteArray &url);
virtual QString vcsGetRepositoryURL(const QString &directory);
virtual QString vcsCreateSnapshot(const QString &topLevel);
virtual QStringList vcsSnapshots(const QString &topLevel);
virtual bool vcsRestoreSnapshot(const QString &topLevel, const QString &name);
......
......@@ -497,6 +497,63 @@ bool MercurialClient::pushSync(const QString &repositoryRoot, const QString &rep
return resp.result == Utils::SynchronousProcessResponse::Finished;
}
bool MercurialClient::clone(const QString &directory, const QString &url)
{
QDir workingDirectory(directory);
QByteArray output;
const unsigned flags = VCSBase::VCSBasePlugin::SshPasswordPrompt|VCSBase::VCSBasePlugin::ShowStdOutInLogWindow
|VCSBase::VCSBasePlugin::ShowSuccessMessage;
if (workingDirectory.exists()) {
// Let's make first init
QStringList arguments(QLatin1String("init"));
if (!executeHgFullySynchronously(workingDirectory.path(), arguments, &output)) {
return false;
}
// Then pull remote repository
arguments.clear();
arguments << QLatin1String("pull") << url;
const Utils::SynchronousProcessResponse resp1 =
executeHgSynchronously(workingDirectory.path(), arguments, flags);
if (resp1.result != Utils::SynchronousProcessResponse::Finished) {
return false;
}
// By now, there is no hgrc file -> create it
QFile hgrc(workingDirectory.path()+"/.hg/hgrc");
hgrc.open(QIODevice::WriteOnly);
hgrc.write(QString("[paths]\ndefault = %1\n").arg(QString(url)).toUtf8());
hgrc.close();
// And last update repository
arguments.clear();
arguments << QLatin1String("update");
const Utils::SynchronousProcessResponse resp2 =
executeHgSynchronously(workingDirectory.path(), arguments, flags);
return resp2.result == Utils::SynchronousProcessResponse::Finished;
} else {
QStringList arguments(QLatin1String("clone"));
arguments << url << workingDirectory.dirName();
workingDirectory.cdUp();
const Utils::SynchronousProcessResponse resp =
executeHgSynchronously(workingDirectory.path(), arguments, flags);
return resp.result == Utils::SynchronousProcessResponse::Finished;
}
}
QString MercurialClient::vcsGetRepositoryURL(const QString &directory)
{
QByteArray output;
QStringList arguments(QLatin1String("showconfig"));
arguments << QLatin1String("paths.default");
if (executeHgFullySynchronously(directory, arguments, &output))
return QString::fromLocal8Bit(output);;
return QString();
}
void MercurialClient::incoming(const QString &repositoryRoot, const QString &repository)
{
QStringList args;
......
......@@ -100,6 +100,8 @@ public:
const QString &commiterInfo,
const QString &commitMessageFile,
bool autoAddRemove = false);
bool clone(const QString &directory, const QString &url);
QString vcsGetRepositoryURL(const QString &directory);
static QString findTopLevelForFile(const QFileInfo &file);
......
......@@ -65,6 +65,8 @@ bool MercurialControl::supportsOperation(Operation operation) const
case Core::IVersionControl::MoveOperation:
case Core::IVersionControl::CreateRepositoryOperation:
case Core::IVersionControl::AnnotateOperation:
case Core::IVersionControl::CheckoutOperation:
case Core::IVersionControl::GetRepositoryRootOperation:
break;
case Core::IVersionControl::OpenOperation:
case Core::IVersionControl::SnapshotOperations:
......@@ -142,6 +144,16 @@ bool MercurialControl::sccManaged(const QString &filename)
return mercurialClient->manifestSync(topLevel, topLevelDir.relativeFilePath(filename));
}
bool MercurialControl::vcsCheckout(const QString &directory, const QByteArray &url)
{
return mercurialClient->clone(directory,url);
}
QString MercurialControl::vcsGetRepositoryURL(const QString &directory)
{
return mercurialClient->vcsGetRepositoryURL(directory);
}
void MercurialControl::changed(const QVariant &v)
{
switch (v.type()) {
......
......@@ -57,6 +57,8 @@ public:
bool vcsDelete(const QString &filename);
bool vcsMove(const QString &from, const QString &to);
bool vcsCreateRepository(const QString &directory);
bool vcsCheckout(const QString &directory, const QByteArray &url);
QString vcsGetRepositoryURL(const QString &directory);
QString vcsCreateSnapshot(const QString &topLevel);
QStringList vcsSnapshots(const QString &topLevel);
bool vcsRestoreSnapshot(const QString &topLevel, const QString &name);
......
......@@ -59,6 +59,8 @@ bool PerforceVersionControl::supportsOperation(Operation operation) const
return true;
case CreateRepositoryOperation:
case SnapshotOperations:
case CheckoutOperation:
case GetRepositoryRootOperation:
break;
}
return false;
......@@ -128,6 +130,16 @@ bool PerforceVersionControl::vcsAnnotate(const QString &file, int line)
return true;
}
bool PerforceVersionControl::vcsCheckout(const QString &/*directory*/,const QByteArray&/*url*/)
{
return false;
}
QString PerforceVersionControl::vcsGetRepositoryURL(const QString &/*directory*/)
{
return QString();
}
bool PerforceVersionControl::managesDirectory(const QString &directory, QString *topLevel) const
{
const bool rc = m_plugin->managesDirectory(directory, topLevel);
......
......@@ -55,6 +55,8 @@ public:
virtual bool vcsDelete(const QString &filename);
virtual bool vcsMove(const QString &from, const QString &to);
virtual bool vcsCreateRepository(const QString &directory);
virtual bool vcsCheckout(const QString &directory, const QByteArray &url);
virtual QString vcsGetRepositoryURL(const QString &directory);
virtual QString vcsCreateSnapshot(const QString &topLevel);
virtual QStringList vcsSnapshots(const QString &topLevel);
virtual bool vcsRestoreSnapshot(const QString &topLevel, const QString &name);
......
......@@ -54,6 +54,8 @@ bool SubversionControl::supportsOperation(Operation operation) const
case DeleteOperation:
case MoveOperation:
case AnnotateOperation:
case CheckoutOperation:
case GetRepositoryRootOperation:
break;
case OpenOperation:
case CreateRepositoryOperation:
......@@ -89,6 +91,16 @@ bool SubversionControl::vcsMove(const QString &from, const QString &to)
return m_plugin->vcsMove(fromInfo.absolutePath(), fromInfo.absoluteFilePath(), toInfo.absoluteFilePath());
}
bool SubversionControl::vcsCheckout(const QString &directory,const QByteArray &url)
{
return m_plugin->vcsCheckout(directory,url);
}
QString SubversionControl::vcsGetRepositoryURL(const QString &directory)
{
return m_plugin->vcsGetRepositoryURL(directory);
}
bool SubversionControl::vcsCreateRepository(const QString &)
{
return false;
......
......@@ -53,6 +53,8 @@ public:
virtual bool vcsDelete(const QString &filename);
virtual bool vcsMove(const QString &from, const QString &to);
virtual bool vcsCreateRepository(const QString &directory);
virtual bool vcsCheckout(const QString &directory, const QByteArray &url);
virtual QString vcsGetRepositoryURL(const QString &directory);
virtual QString vcsCreateSnapshot(const QString &topLevel);
virtual QStringList vcsSnapshots(const QString &topLevel);
......
......@@ -65,13 +65,14 @@
#include <QtCore/QTextCodec>
#include <QtCore/QtPlugin>
#include <QtCore/QProcessEnvironment>
#include <QtCore/QUrl>
#include <QtGui/QAction>
#include <QtGui/QFileDialog>
#include <QtGui/QMainWindow>
#include <QtGui/QMenu>
#include <QtGui/QMessageBox>
#include <QtGui/QInputDialog>
#include <QtXml/QXmlStreamReader>
#include <limits.h>
using namespace Subversion::Internal;
......@@ -1224,6 +1225,74 @@ bool SubversionPlugin::vcsMove(const QString &workingDir, const QString &from, c
return !response.error;
}
bool SubversionPlugin::vcsCheckout(const QString &directory, const QByteArray &url)
{
QUrl tempUrl;
tempUrl.setEncodedUrl(url);
QString username = tempUrl.userName();
QString password = tempUrl.password();
QStringList args = QStringList(QLatin1String("checkout"));
args << QLatin1String(nonInteractiveOptionC) ;
if(!username.isEmpty() && !password.isEmpty())
{
// If url contains username and password we have to use separate username and password
// arguments instead of passing those in the url. Otherwise the subversion 'non-interactive'
// authentication will always fail (if the username and password data are not stored locally),
// if for example we are logging into a new host for the first time using svn. There seems to
// be a bug in subversion, so this might get fixed in the future.
tempUrl.setUserInfo("");
args << tempUrl.toEncoded() << directory;
const SubversionResponse response = runSvn(directory, username, password, args, m_settings.longTimeOutMS(),
VCSBase::VCSBasePlugin::SshPasswordPrompt);
return !response.error;
} else {
args << url << directory;
const SubversionResponse response = runSvn(directory, args, m_settings.longTimeOutMS(),
VCSBase::VCSBasePlugin::SshPasswordPrompt);
return !response.error;
}
}
QString SubversionPlugin::vcsGetRepositoryURL(const QString &directory)
{
QXmlStreamReader xml;
QStringList args = QStringList(QLatin1String("info"));
args << QLatin1String("--xml");
const SubversionResponse response = runSvn(directory, args, m_settings.longTimeOutMS(), SuppressCommandLogging);
xml.addData(response.stdOut);
bool repo = false;
bool root = false;
while(!xml.atEnd() && !xml.hasError()) {
switch(xml.readNext()) {
case QXmlStreamReader::StartDocument:
break;
case QXmlStreamReader::StartElement:
if(xml.name() == QLatin1String("repository"))
repo = true;
else if(repo && xml.name() == QLatin1String("root"))
root = true;
break;
case QXmlStreamReader::EndElement:
if(xml.name() == QLatin1String("repository"))
repo = false;
else if(repo && xml.name() == QLatin1String("root"))
root = false;
break;
case QXmlStreamReader::Characters:
if (repo && root)
return xml.text().toString();
break;
default:
break;
}
}
return QString();
}
/* Subversion has ".svn" directory in each directory
* it manages. The top level is the first directory
* under the directory that does not have a ".svn". */
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment