Gerrit: Refactor actual output parsing from its setup

Change-Id: I5cf4c75dfbe1620a59cebc756e4e138957cf635e
Reviewed-by: Tobias Hunger <tobias.hunger@qt.io>
This commit is contained in:
Orgad Shaneh
2017-02-23 21:29:46 +02:00
committed by Orgad Shaneh
parent d64e17ad55
commit 1e89c617f4

View File

@@ -547,13 +547,8 @@ void GerritModel::setState(GerritModel::QueryState s)
\endcode \endcode
*/ */
static bool parseOutput(const QSharedPointer<GerritParameters> &parameters, static GerritChangePtr parseSshOutput(const QJsonObject &object)
const GerritServer &server,
const QByteArray &output,
QList<GerritChangePtr> &result)
{ {
// The output consists of separate lines containing a document each
const QString typeKey = "type";
const QString dependsOnKey = "dependsOn"; const QString dependsOnKey = "dependsOn";
const QString neededByKey = "neededBy"; const QString neededByKey = "neededBy";
const QString branchKey = "branch"; const QString branchKey = "branch";
@@ -572,33 +567,10 @@ static bool parseOutput(const QSharedPointer<GerritParameters> &parameters,
const QString approvalsValueKey = "value"; const QString approvalsValueKey = "value";
const QString approvalsByKey = "by"; const QString approvalsByKey = "by";
const QString lastUpdatedKey = "lastUpdated"; const QString lastUpdatedKey = "lastUpdated";
const QList<QByteArray> lines = output.split('\n');
const QString approvalsTypeKey = "type"; const QString approvalsTypeKey = "type";
const QString approvalsDescriptionKey = "description"; const QString approvalsDescriptionKey = "description";
bool res = true;
result.clear();
result.reserve(lines.size());
for (const QByteArray &line : lines) {
if (line.isEmpty())
continue;
QJsonParseError error;
const QJsonDocument doc = QJsonDocument::fromJson(line, &error);
if (doc.isNull()) {
QString errorMessage = GerritModel::tr("Parse error: \"%1\" -> %2")
.arg(QString::fromLocal8Bit(line))
.arg(error.errorString());
qWarning() << errorMessage;
VcsOutputWindow::appendError(errorMessage);
res = false;
continue;
}
GerritChangePtr change(new GerritChange); GerritChangePtr change(new GerritChange);
const QJsonObject object = doc.object();
// Skip stats line: {"type":"stats","rowCount":9,"runTimeMilliseconds":13}
if (!object.value(typeKey).toString().isEmpty())
continue;
// Read current patch set. // Read current patch set.
const QJsonObject patchSet = object.value(patchSetKey).toObject(); const QJsonObject patchSet = object.value(patchSetKey).toObject();
change->currentPatchSet.patchSetNumber = qMax(1, patchSet.value(numberKey).toString().toInt()); change->currentPatchSet.patchSetNumber = qMax(1, patchSet.value(numberKey).toString().toInt());
@@ -622,8 +594,6 @@ static bool parseOutput(const QSharedPointer<GerritParameters> &parameters,
// Remaining // Remaining
change->number = object.value(numberKey).toString().toInt(); change->number = object.value(numberKey).toString().toInt();
change->url = object.value(urlKey).toString(); change->url = object.value(urlKey).toString();
if (change->url.isEmpty()) // No "canonicalWebUrl" is in gerrit.config.
change->url = defaultUrl(parameters, server, change->number);
change->title = object.value(titleKey).toString(); change->title = object.value(titleKey).toString();
const QJsonObject ownerJ = object.value(ownerKey).toObject(); const QJsonObject ownerJ = object.value(ownerKey).toObject();
change->owner = ownerJ.value(ownerNameKey).toString(); change->owner = ownerJ.value(ownerNameKey).toString();
@@ -634,14 +604,6 @@ static bool parseOutput(const QSharedPointer<GerritParameters> &parameters,
change->status = object.value(statusKey).toString(); change->status = object.value(statusKey).toString();
if (const int timeT = qRound(object.value(lastUpdatedKey).toDouble())) if (const int timeT = qRound(object.value(lastUpdatedKey).toDouble()))
change->lastUpdated = QDateTime::fromTime_t(timeT); change->lastUpdated = QDateTime::fromTime_t(timeT);
if (change->isValid()) {
result.push_back(change);
} else {
qWarning("%s: Parse error: '%s'.", Q_FUNC_INFO, line.constData());
VcsOutputWindow::appendError(GerritModel::tr("Parse error: \"%1\"")
.arg(QString::fromLocal8Bit(line)));
res = false;
}
// Read out dependencies // Read out dependencies
const QJsonValue dependsOnValue = object.value(dependsOnKey); const QJsonValue dependsOnValue = object.value(dependsOnKey);
if (dependsOnValue.isArray()) { if (dependsOnValue.isArray()) {
@@ -662,6 +624,53 @@ static bool parseOutput(const QSharedPointer<GerritParameters> &parameters,
change->neededByNumber = first.toObject()[numberKey].toString().toInt(); change->neededByNumber = first.toObject()[numberKey].toString().toInt();
} }
} }
return change;
}
static bool parseOutput(const QSharedPointer<GerritParameters> &parameters,
const GerritServer &server,
const QByteArray &output,
QList<GerritChangePtr> &result)
{
// The output consists of separate lines containing a document each
// Add a comma after each line (except the last), and enclose it as an array
QByteArray adaptedOutput = '[' + output + ']';
adaptedOutput.replace('\n', ',');
const int lastComma = adaptedOutput.lastIndexOf(',');
if (lastComma >= 0)
adaptedOutput[lastComma] = '\n';
bool res = true;
QJsonParseError error;
const QJsonDocument doc = QJsonDocument::fromJson(adaptedOutput, &error);
if (doc.isNull()) {
QString errorMessage = GerritModel::tr("Parse error: \"%1\" -> %2")
.arg(QString::fromUtf8(output))
.arg(error.errorString());
qWarning() << errorMessage;
VcsOutputWindow::appendError(errorMessage);
res = false;
}
const QJsonArray rootArray = doc.array();
result.clear();
result.reserve(rootArray.count());
for (const QJsonValue &value : rootArray) {
const QJsonObject object = value.toObject();
// Skip stats line: {"type":"stats","rowCount":9,"runTimeMilliseconds":13}
if (object.contains("type"))
continue;
GerritChangePtr change = parseSshOutput(object);
if (change->isValid()) {
if (change->url.isEmpty()) // No "canonicalWebUrl" is in gerrit.config.
change->url = defaultUrl(parameters, server, change->number);
result.push_back(change);
} else {
const QByteArray jsonObject = QJsonDocument(object).toJson();
qWarning("%s: Parse error: '%s'.", Q_FUNC_INFO, jsonObject.constData());
VcsOutputWindow::appendError(GerritModel::tr("Parse error: \"%1\"")
.arg(QString::fromUtf8(jsonObject)));
res = false;
}
} }
return res; return res;
} }