vcsbase: refactor status parsing in VCSBaseClient

This impacts Bazaar and Mercurial plugins

Change-Id: Ife1e83083b268e597928fbae30378e488e31ee96
Merge-request: 358
Reviewed-by: Tobias Hunger <tobias.hunger@nokia.com>
Reviewed-on: http://codereview.qt.nokia.com/3335
This commit is contained in:
cerf
2011-08-22 15:33:03 +00:00
committed by Tobias Hunger
parent 96819ddb7a
commit 3907824b4d
14 changed files with 82 additions and 63 deletions

View File

@@ -234,48 +234,48 @@ QStringList BazaarClient::viewArguments(const QString &revision) const
return args; return args;
} }
QPair<QString, QString> BazaarClient::parseStatusLine(const QString &line) const BazaarClient::StatusItem BazaarClient::parseStatusLine(const QString &line) const
{ {
QPair<QString, QString> status; StatusItem item;
if (!line.isEmpty()) { if (!line.isEmpty()) {
const QChar flagVersion = line[0]; const QChar flagVersion = line[0];
if (flagVersion == QLatin1Char('+')) if (flagVersion == QLatin1Char('+'))
status.first = QLatin1String("Versioned"); item.flags = QLatin1String("Versioned");
else if (flagVersion == QLatin1Char('-')) else if (flagVersion == QLatin1Char('-'))
status.first = QLatin1String("Unversioned"); item.flags = QLatin1String("Unversioned");
else if (flagVersion == QLatin1Char('R')) else if (flagVersion == QLatin1Char('R'))
status.first = QLatin1String("Renamed"); item.flags = QLatin1String("Renamed");
else if (flagVersion == QLatin1Char('?')) else if (flagVersion == QLatin1Char('?'))
status.first = QLatin1String("Unknown"); item.flags = QLatin1String("Unknown");
else if (flagVersion == QLatin1Char('X')) else if (flagVersion == QLatin1Char('X'))
status.first = QLatin1String("Nonexistent"); item.flags = QLatin1String("Nonexistent");
else if (flagVersion == QLatin1Char('C')) else if (flagVersion == QLatin1Char('C'))
status.first = QLatin1String("Conflict"); item.flags = QLatin1String("Conflict");
else if (flagVersion == QLatin1Char('P')) else if (flagVersion == QLatin1Char('P'))
status.first = QLatin1String("PendingMerge"); item.flags = QLatin1String("PendingMerge");
const int lineLength = line.length(); const int lineLength = line.length();
if (lineLength >= 2) { if (lineLength >= 2) {
const QChar flagContents = line[1]; const QChar flagContents = line[1];
if (flagContents == QLatin1Char('N')) if (flagContents == QLatin1Char('N'))
status.first = QLatin1String("Created"); item.flags = QLatin1String("Created");
else if (flagContents == QLatin1Char('D')) else if (flagContents == QLatin1Char('D'))
status.first = QLatin1String("Deleted"); item.flags = QLatin1String("Deleted");
else if (flagContents == QLatin1Char('K')) else if (flagContents == QLatin1Char('K'))
status.first = QLatin1String("KindChanged"); item.flags = QLatin1String("KindChanged");
else if (flagContents == QLatin1Char('M')) else if (flagContents == QLatin1Char('M'))
status.first = QLatin1String("Modified"); item.flags = QLatin1String("Modified");
} }
if (lineLength >= 3) { if (lineLength >= 3) {
const QChar flagExec = line[2]; const QChar flagExec = line[2];
if (flagExec == QLatin1Char('*')) if (flagExec == QLatin1Char('*'))
status.first = QLatin1String("ExecuteBitChanged"); item.flags = QLatin1String("ExecuteBitChanged");
} }
// The status string should be similar to "xxx file_with_changes" // The status string should be similar to "xxx file_with_changes"
// so just should take the file name part and store it // so just should take the file name part and store it
status.second = line.mid(4); item.file = line.mid(4);
} }
return status; return item;
} }
// Collect all parameters required for a diff or log to be able to associate // Collect all parameters required for a diff or log to be able to associate

View File

@@ -86,7 +86,7 @@ protected:
QStringList statusArguments(const QString &file) const; QStringList statusArguments(const QString &file) const;
QStringList viewArguments(const QString &revision) const; QStringList viewArguments(const QString &revision) const;
QPair<QString, QString> parseStatusLine(const QString &line) const; StatusItem parseStatusLine(const QString &line) const;
private: private:
friend class CloneWizard; friend class CloneWizard;
}; };

View File

@@ -541,17 +541,17 @@ void BazaarPlugin::commit()
m_submitRepository = state.topLevel(); m_submitRepository = state.topLevel();
connect(m_client, SIGNAL(parsedStatus(QList<QPair<QString,QString> >)), connect(m_client, SIGNAL(parsedStatus(QList<VCSBase::VCSBaseClient::StatusItem>)),
this, SLOT(showCommitWidget(QList<QPair<QString,QString> >))); this, SLOT(showCommitWidget(QList<VCSBase::VCSBaseClient::StatusItem>)));
m_client->statusWithSignal(m_submitRepository); m_client->statusWithSignal(m_submitRepository);
} }
void BazaarPlugin::showCommitWidget(const QList<QPair<QString, QString> > &status) void BazaarPlugin::showCommitWidget(const QList<VCSBase::VCSBaseClient::StatusItem> &status)
{ {
VCSBase::VCSBaseOutputWindow *outputWindow = VCSBase::VCSBaseOutputWindow::instance(); VCSBase::VCSBaseOutputWindow *outputWindow = VCSBase::VCSBaseOutputWindow::instance();
//Once we receive our data release the connection so it can be reused elsewhere //Once we receive our data release the connection so it can be reused elsewhere
disconnect(m_client, SIGNAL(parsedStatus(QList<QPair<QString,QString> >)), disconnect(m_client, SIGNAL(parsedStatus(QList<VCSBase::VCSBaseClient::StatusItem>)),
this, SLOT(showCommitWidget(QList<QPair<QString,QString> >))); this, SLOT(showCommitWidget(QList<VCSBase::VCSBaseClient::StatusItem>)));
if (status.isEmpty()) { if (status.isEmpty()) {
outputWindow->appendError(tr("There are no changes to commit.")); outputWindow->appendError(tr("There are no changes to commit."));

View File

@@ -36,6 +36,7 @@
#include "bazaarsettings.h" #include "bazaarsettings.h"
#include <vcsbase/vcsbaseclientsettings.h> #include <vcsbase/vcsbaseclientsettings.h>
#include <vcsbase/vcsbaseclient.h>
#include <vcsbase/vcsbaseplugin.h> #include <vcsbase/vcsbaseplugin.h>
#include <coreplugin/icontext.h> #include <coreplugin/icontext.h>
@@ -113,7 +114,7 @@ private slots:
void push(); void push();
void update(); void update();
void commit(); void commit();
void showCommitWidget(const QList<QPair<QString, QString> > &status); void showCommitWidget(const QList<VCSBase::VCSBaseClient::StatusItem> &status);
void commitFromEditor(); void commitFromEditor();
void diffFromEditorSelected(const QStringList &files); void diffFromEditorSelected(const QStringList &files);

View File

@@ -62,7 +62,7 @@ BazaarCommitWidget *CommitEditor::commitWidget()
void CommitEditor::setFields(const BranchInfo &branch, void CommitEditor::setFields(const BranchInfo &branch,
const QString &userName, const QString &email, const QString &userName, const QString &email,
const QList<QPair<QString, QString> > &repoStatus) const QList<VCSBase::VCSBaseClient::StatusItem> &repoStatus)
{ {
BazaarCommitWidget *bazaarWidget = commitWidget(); BazaarCommitWidget *bazaarWidget = commitWidget();
if (!bazaarWidget) if (!bazaarWidget)
@@ -71,9 +71,8 @@ void CommitEditor::setFields(const BranchInfo &branch,
bazaarWidget->setFields(branch, userName, email); bazaarWidget->setFields(branch, userName, email);
m_fileModel = new VCSBase::SubmitFileModel(this); m_fileModel = new VCSBase::SubmitFileModel(this);
typedef QPair<QString, QString> StringPair; foreach (const VCSBase::VCSBaseClient::StatusItem &item, repoStatus)
foreach (const StringPair &status, repoStatus) if (item.flags != QLatin1String("Unknown"))
if (status.first != QLatin1String("Unknown")) m_fileModel->addFile(item.file, item.flags, true);
m_fileModel->addFile(status.second, status.first, true);
setFileModel(m_fileModel); setFileModel(m_fileModel);
} }

View File

@@ -33,6 +33,7 @@
#ifndef COMMITEDITOR_H #ifndef COMMITEDITOR_H
#define COMMITEDITOR_H #define COMMITEDITOR_H
#include <vcsbase/vcsbaseclient.h>
#include <vcsbase/vcsbasesubmiteditor.h> #include <vcsbase/vcsbasesubmiteditor.h>
namespace VCSBase { namespace VCSBase {
@@ -54,7 +55,7 @@ public:
void setFields(const BranchInfo &branch, void setFields(const BranchInfo &branch,
const QString &userName, const QString &email, const QString &userName, const QString &email,
const QList<QPair<QString, QString> > &repoStatus); const QList<VCSBase::VCSBaseClient::StatusItem> &repoStatus);
const BazaarCommitWidget *commitWidget() const; const BazaarCommitWidget *commitWidget() const;

View File

@@ -55,7 +55,7 @@ MercurialCommitWidget *CommitEditor::commitWidget()
void CommitEditor::setFields(const QFileInfo &repositoryRoot, const QString &branch, void CommitEditor::setFields(const QFileInfo &repositoryRoot, const QString &branch,
const QString &userName, const QString &email, const QString &userName, const QString &email,
const QList<QPair<QString, QString> > &repoStatus) const QList<VCSBase::VCSBaseClient::StatusItem> &repoStatus)
{ {
MercurialCommitWidget *mercurialWidget = commitWidget(); MercurialCommitWidget *mercurialWidget = commitWidget();
if (!mercurialWidget) if (!mercurialWidget)
@@ -66,23 +66,22 @@ void CommitEditor::setFields(const QFileInfo &repositoryRoot, const QString &bra
fileModel = new VCSBase::SubmitFileModel(this); fileModel = new VCSBase::SubmitFileModel(this);
//TODO Messy tidy this up //TODO Messy tidy this up
typedef QPair<QString, QString> StringStringPair;
QStringList shouldTrack; QStringList shouldTrack;
foreach (const StringStringPair &status, repoStatus) { foreach (const VCSBase::VCSBaseClient::StatusItem &item, repoStatus) {
if (status.first == QLatin1String("Untracked")) if (item.flags == QLatin1String("Untracked"))
shouldTrack.append(status.second); shouldTrack.append(item.file);
else else
fileModel->addFile(status.second, status.first, false); fileModel->addFile(item.file, item.flags, false);
} }
VCSBase::VCSBaseSubmitEditor::filterUntrackedFilesOfProject(repositoryRoot.absoluteFilePath(), VCSBase::VCSBaseSubmitEditor::filterUntrackedFilesOfProject(repositoryRoot.absoluteFilePath(),
&shouldTrack); &shouldTrack);
foreach (const QString &track, shouldTrack) { foreach (const QString &track, shouldTrack) {
foreach (const StringStringPair &status, repoStatus) { foreach (const VCSBase::VCSBaseClient::StatusItem &item, repoStatus) {
if (status.second == track) if (item.file == track)
fileModel->addFile(status.second, status.first, false); fileModel->addFile(item.file, item.flags, false);
} }
} }

View File

@@ -33,6 +33,7 @@
#ifndef COMMITEDITOR_H #ifndef COMMITEDITOR_H
#define COMMITEDITOR_H #define COMMITEDITOR_H
#include <vcsbase/vcsbaseclient.h>
#include <vcsbase/vcsbasesubmiteditor.h> #include <vcsbase/vcsbasesubmiteditor.h>
#include <QtCore/QFileInfo> #include <QtCore/QFileInfo>
@@ -55,7 +56,7 @@ public:
void setFields(const QFileInfo &repositoryRoot, const QString &branch, void setFields(const QFileInfo &repositoryRoot, const QString &branch,
const QString &userName, const QString &email, const QString &userName, const QString &email,
const QList<QPair<QString, QString> > &repoStatus); const QList<VCSBase::VCSBaseClient::StatusItem> &repoStatus);
QString committerInfo(); QString committerInfo();
QString repoRoot(); QString repoRoot();

View File

@@ -452,29 +452,29 @@ QStringList MercurialClient::viewArguments(const QString &revision) const
return args; return args;
} }
QPair<QString, QString> MercurialClient::parseStatusLine(const QString &line) const MercurialClient::StatusItem MercurialClient::parseStatusLine(const QString &line) const
{ {
QPair<QString, QString> status; StatusItem item;
if (!line.isEmpty()) if (!line.isEmpty())
{ {
if (line.startsWith(QLatin1Char('M'))) if (line.startsWith(QLatin1Char('M')))
status.first = QLatin1String("Modified"); item.flags = QLatin1String("Modified");
else if (line.startsWith(QLatin1Char('A'))) else if (line.startsWith(QLatin1Char('A')))
status.first = QLatin1String("Added"); item.flags = QLatin1String("Added");
else if (line.startsWith(QLatin1Char('R'))) else if (line.startsWith(QLatin1Char('R')))
status.first = QLatin1String("Removed"); item.flags = QLatin1String("Removed");
else if (line.startsWith(QLatin1Char('!'))) else if (line.startsWith(QLatin1Char('!')))
status.first = QLatin1String("Deleted"); item.flags = QLatin1String("Deleted");
else if (line.startsWith(QLatin1Char('?'))) else if (line.startsWith(QLatin1Char('?')))
status.first = QLatin1String("Untracked"); item.flags = QLatin1String("Untracked");
else else
return status; return item;
//the status line should be similar to "M file_with_changes" //the status line should be similar to "M file_with_changes"
//so just should take the file name part and store it //so just should take the file name part and store it
status.second = line.mid(2); item.file = line.mid(2);
} }
return status; return item;
} }
// Collect all parameters required for a diff to be able to associate them // Collect all parameters required for a diff to be able to associate them

View File

@@ -100,7 +100,7 @@ protected:
QStringList statusArguments(const QString &file) const; QStringList statusArguments(const QString &file) const;
QStringList viewArguments(const QString &revision) const; QStringList viewArguments(const QString &revision) const;
QPair<QString, QString> parseStatusLine(const QString &line) const; StatusItem parseStatusLine(const QString &line) const;
}; };
} //namespace Internal } //namespace Internal

View File

@@ -566,18 +566,18 @@ void MercurialPlugin::commit()
m_submitRepository = state.topLevel(); m_submitRepository = state.topLevel();
connect(m_client, SIGNAL(parsedStatus(QList<QPair<QString,QString> >)), connect(m_client, SIGNAL(parsedStatus(QList<VCSBase::VCSBaseClient::StatusItem>)),
this, SLOT(showCommitWidget(QList<QPair<QString,QString> >))); this, SLOT(showCommitWidget(QList<VCSBase::VCSBaseClient::StatusItem>)));
m_client->statusWithSignal(m_submitRepository); m_client->statusWithSignal(m_submitRepository);
} }
void MercurialPlugin::showCommitWidget(const QList<QPair<QString, QString> > &status) void MercurialPlugin::showCommitWidget(const QList<VCSBase::VCSBaseClient::StatusItem> &status)
{ {
VCSBase::VCSBaseOutputWindow *outputWindow = VCSBase::VCSBaseOutputWindow::instance(); VCSBase::VCSBaseOutputWindow *outputWindow = VCSBase::VCSBaseOutputWindow::instance();
//Once we receive our data release the connection so it can be reused elsewhere //Once we receive our data release the connection so it can be reused elsewhere
disconnect(m_client, SIGNAL(parsedStatus(QList<QPair<QString,QString> >)), disconnect(m_client, SIGNAL(parsedStatus(QList<VCSBase::VCSBaseClient::StatusItem>)),
this, SLOT(showCommitWidget(QList<QPair<QString,QString> >))); this, SLOT(showCommitWidget(QList<VCSBase::VCSBaseClient::StatusItem>)));
if (status.isEmpty()) { if (status.isEmpty()) {
outputWindow->appendError(tr("There are no changes to commit.")); outputWindow->appendError(tr("There are no changes to commit."));

View File

@@ -35,6 +35,7 @@
#include "mercurialsettings.h" #include "mercurialsettings.h"
#include <vcsbase/vcsbaseclient.h>
#include <vcsbase/vcsbaseplugin.h> #include <vcsbase/vcsbaseplugin.h>
#include <coreplugin/icontext.h> #include <coreplugin/icontext.h>
@@ -118,7 +119,7 @@ private slots:
void incoming(); void incoming();
void outgoing(); void outgoing();
void commit(); void commit();
void showCommitWidget(const QList<QPair<QString, QString> > &status); void showCommitWidget(const QList<VCSBase::VCSBaseClient::StatusItem> &status);
void commitFromEditor(); void commitFromEditor();
void diffFromEditorSelected(const QStringList &files); void diffFromEditorSelected(const QStringList &files);

View File

@@ -102,17 +102,17 @@ VCSBaseClientPrivate::VCSBaseClientPrivate(VCSBaseClient *client, VCSBaseClientS
void VCSBaseClientPrivate::statusParser(QByteArray data) void VCSBaseClientPrivate::statusParser(QByteArray data)
{ {
QList<QPair<QString, QString> > statusList; QList<VCSBaseClient::StatusItem> lineInfoList;
QStringList rawStatusList = QTextCodec::codecForLocale()->toUnicode(data).split(QLatin1Char('\n')); QStringList rawStatusList = QTextCodec::codecForLocale()->toUnicode(data).split(QLatin1Char('\n'));
foreach (const QString &string, rawStatusList) { foreach (const QString &string, rawStatusList) {
QPair<QString, QString> status = m_client->parseStatusLine(string); const VCSBaseClient::StatusItem lineInfo = m_client->parseStatusLine(string);
if (!status.first.isEmpty() && !status.second.isEmpty()) if (!lineInfo.flags.isEmpty() && !lineInfo.file.isEmpty())
statusList.append(status); lineInfoList.append(lineInfo);
} }
emit m_client->parsedStatus(statusList); emit m_client->parsedStatus(lineInfoList);
} }
void VCSBaseClientPrivate::annotateRevision(QString source, QString change, int lineNumber) void VCSBaseClientPrivate::annotateRevision(QString source, QString change, int lineNumber)
@@ -131,6 +131,15 @@ void VCSBaseClientPrivate::saveSettings()
m_clientSettings->writeSettings(m_core->settings()); m_clientSettings->writeSettings(m_core->settings());
} }
VCSBaseClient::StatusItem::StatusItem()
{
}
VCSBaseClient::StatusItem::StatusItem(const QString &s, const QString &f) :
flags(s), file(f)
{
}
VCSBaseClient::VCSBaseClient(VCSBaseClientSettings *settings) : VCSBaseClient::VCSBaseClient(VCSBaseClientSettings *settings) :
d(new VCSBaseClientPrivate(this, settings)) d(new VCSBaseClientPrivate(this, settings))
{ {

View File

@@ -67,6 +67,14 @@ class VCSBASE_EXPORT VCSBaseClient : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
struct VCSBASE_EXPORT StatusItem
{
StatusItem();
StatusItem(const QString &s, const QString &f);
QString flags;
QString file;
};
explicit VCSBaseClient(VCSBaseClientSettings *settings); explicit VCSBaseClient(VCSBaseClientSettings *settings);
~VCSBaseClient(); ~VCSBaseClient();
virtual bool synchronousCreateRepository(const QString &workingDir); virtual bool synchronousCreateRepository(const QString &workingDir);
@@ -107,7 +115,7 @@ public:
virtual VCSBaseClientSettings *settings() const; virtual VCSBaseClientSettings *settings() const;
signals: signals:
void parsedStatus(const QList<QPair<QString, QString> > &statusList); void parsedStatus(const QList<VCSBase::VCSBaseClient::StatusItem> &statusList);
// Passes on changed signals from VCSJob to Control // Passes on changed signals from VCSJob to Control
void changed(const QVariant &v); void changed(const QVariant &v);
@@ -166,7 +174,7 @@ protected:
virtual QStringList statusArguments(const QString &file) const = 0; virtual QStringList statusArguments(const QString &file) const = 0;
virtual QStringList viewArguments(const QString &revision) const = 0; virtual QStringList viewArguments(const QString &revision) const = 0;
virtual QPair<QString, QString> parseStatusLine(const QString &line) const = 0; virtual StatusItem parseStatusLine(const QString &line) const = 0;
QString vcsEditorTitle(const QString &vcsCmd, const QString &sourceId) const; QString vcsEditorTitle(const QString &vcsCmd, const QString &sourceId) const;
void enqueueJob(const QSharedPointer<VCSJob> &); void enqueueJob(const QSharedPointer<VCSJob> &);