forked from qt-creator/qt-creator
Provide functionality for fetching project information
Change-Id: Id0968c08eb3017eb6f902c3cea3a363bc3f0c35c Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
@@ -89,4 +89,9 @@ void AxivionOutputPane::goToPrev()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AxivionOutputPane::updateDashboard()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
} // Axivion::Internal
|
} // Axivion::Internal
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ public:
|
|||||||
void goToNext() override;
|
void goToNext() override;
|
||||||
void goToPrev() override;
|
void goToPrev() override;
|
||||||
|
|
||||||
|
void updateDashboard();
|
||||||
private:
|
private:
|
||||||
QStackedWidget *m_outputWidget = nullptr;
|
QStackedWidget *m_outputWidget = nullptr;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,14 +5,18 @@
|
|||||||
|
|
||||||
#include "axivionoutputpane.h"
|
#include "axivionoutputpane.h"
|
||||||
#include "axivionprojectsettings.h"
|
#include "axivionprojectsettings.h"
|
||||||
|
#include "axivionquery.h"
|
||||||
|
#include "axivionresultparser.h"
|
||||||
#include "axivionsettings.h"
|
#include "axivionsettings.h"
|
||||||
#include "axivionsettingspage.h"
|
#include "axivionsettingspage.h"
|
||||||
#include "axiviontr.h"
|
#include "axiviontr.h"
|
||||||
|
|
||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
|
#include <coreplugin/messagemanager.h>
|
||||||
#include <extensionsystem/pluginmanager.h>
|
#include <extensionsystem/pluginmanager.h>
|
||||||
#include <projectexplorer/project.h>
|
#include <projectexplorer/project.h>
|
||||||
#include <projectexplorer/projectpanelfactory.h>
|
#include <projectexplorer/projectpanelfactory.h>
|
||||||
|
#include <projectexplorer/session.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
#ifdef LICENSECHECKER
|
#ifdef LICENSECHECKER
|
||||||
@@ -20,16 +24,22 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
namespace Axivion::Internal {
|
namespace Axivion::Internal {
|
||||||
|
|
||||||
class AxivionPluginPrivate
|
class AxivionPluginPrivate : public QObject
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
void fetchProjectInfo(const QString &projectName);
|
||||||
|
void handleProjectInfo(const ProjectInfo &info);
|
||||||
|
|
||||||
AxivionSettings axivionSettings;
|
AxivionSettings axivionSettings;
|
||||||
AxivionSettingsPage axivionSettingsPage{&axivionSettings};
|
AxivionSettingsPage axivionSettingsPage{&axivionSettings};
|
||||||
AxivionOutputPane axivionOutputPane;
|
AxivionOutputPane axivionOutputPane;
|
||||||
QHash<ProjectExplorer::Project *, AxivionProjectSettings *> projectSettings;
|
QHash<ProjectExplorer::Project *, AxivionProjectSettings *> projectSettings;
|
||||||
|
ProjectInfo currentProjectInfo;
|
||||||
|
bool runningQuery = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
static AxivionPlugin *s_instance = nullptr;
|
static AxivionPlugin *s_instance = nullptr;
|
||||||
@@ -78,9 +88,26 @@ bool AxivionPlugin::initialize(const QStringList &arguments, QString *errorMessa
|
|||||||
return new AxivionProjectSettingsWidget(project);
|
return new AxivionProjectSettingsWidget(project);
|
||||||
});
|
});
|
||||||
ProjectExplorer::ProjectPanelFactory::registerFactory(panelFactory);
|
ProjectExplorer::ProjectPanelFactory::registerFactory(panelFactory);
|
||||||
|
connect(ProjectExplorer::SessionManager::instance(),
|
||||||
|
&ProjectExplorer::SessionManager::startupProjectChanged,
|
||||||
|
this, &AxivionPlugin::onStartupProjectChanged);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AxivionPlugin::onStartupProjectChanged()
|
||||||
|
{
|
||||||
|
QTC_ASSERT(dd, return);
|
||||||
|
ProjectExplorer::Project *project = ProjectExplorer::SessionManager::startupProject();
|
||||||
|
if (!project) {
|
||||||
|
dd->currentProjectInfo = ProjectInfo();
|
||||||
|
dd->axivionOutputPane.updateDashboard();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const AxivionProjectSettings *projSettings = projectSettings(project);
|
||||||
|
dd->fetchProjectInfo(projSettings->dashboardProjectName());
|
||||||
|
}
|
||||||
|
|
||||||
AxivionSettings *AxivionPlugin::settings()
|
AxivionSettings *AxivionPlugin::settings()
|
||||||
{
|
{
|
||||||
QTC_ASSERT(dd, return nullptr);
|
QTC_ASSERT(dd, return nullptr);
|
||||||
@@ -116,4 +143,44 @@ bool AxivionPlugin::handleCertificateIssue()
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AxivionPlugin::fetchProjectInfo(const QString &projectName)
|
||||||
|
{
|
||||||
|
QTC_ASSERT(dd, return);
|
||||||
|
dd->fetchProjectInfo(projectName);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AxivionPluginPrivate::fetchProjectInfo(const QString &projectName)
|
||||||
|
{
|
||||||
|
if (runningQuery) { // re-schedule
|
||||||
|
QTimer::singleShot(3000, [this, projectName]{ fetchProjectInfo(projectName); });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (projectName.isEmpty()) {
|
||||||
|
currentProjectInfo = ProjectInfo();
|
||||||
|
axivionOutputPane.updateDashboard();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
runningQuery = true;
|
||||||
|
|
||||||
|
AxivionQuery query(AxivionQuery::ProjectInfo, {projectName});
|
||||||
|
AxivionQueryRunner *runner = new AxivionQueryRunner(query, this);
|
||||||
|
connect(runner, &AxivionQueryRunner::resultRetrieved, this, [this](const QByteArray &result){
|
||||||
|
handleProjectInfo(ResultParser::parseProjectInfo(result));
|
||||||
|
});
|
||||||
|
connect(runner, &AxivionQueryRunner::finished, [runner]{ runner->deleteLater(); });
|
||||||
|
runner->start();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AxivionPluginPrivate::handleProjectInfo(const ProjectInfo &info)
|
||||||
|
{
|
||||||
|
runningQuery = false;
|
||||||
|
if (!info.error.isEmpty()) {
|
||||||
|
Core::MessageManager::writeFlashing("Axivion: " + info.error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentProjectInfo = info;
|
||||||
|
axivionOutputPane.updateDashboard();
|
||||||
|
}
|
||||||
|
|
||||||
} // Axivion::Internal
|
} // Axivion::Internal
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ public:
|
|||||||
static AxivionProjectSettings *projectSettings(ProjectExplorer::Project *project);
|
static AxivionProjectSettings *projectSettings(ProjectExplorer::Project *project);
|
||||||
|
|
||||||
static bool handleCertificateIssue();
|
static bool handleCertificateIssue();
|
||||||
|
static void fetchProjectInfo(const QString &projectName);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void settingsChanged();
|
void settingsChanged();
|
||||||
@@ -33,6 +34,7 @@ signals:
|
|||||||
private:
|
private:
|
||||||
bool initialize(const QStringList &arguments, QString *errorMessage) final;
|
bool initialize(const QStringList &arguments, QString *errorMessage) final;
|
||||||
void extensionsInitialized() final {}
|
void extensionsInitialized() final {}
|
||||||
|
void onStartupProjectChanged();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // Axivion::Internal
|
} // Axivion::Internal
|
||||||
|
|||||||
@@ -136,8 +136,10 @@ void AxivionProjectSettingsWidget::linkProject()
|
|||||||
const QList<QTreeWidgetItem *> selected = m_dashboardProjects->selectedItems();
|
const QList<QTreeWidgetItem *> selected = m_dashboardProjects->selectedItems();
|
||||||
QTC_ASSERT(selected.size() == 1, return);
|
QTC_ASSERT(selected.size() == 1, return);
|
||||||
|
|
||||||
m_projectSettings->setDashboardProjectName(selected.first()->text(0));
|
const QString projectName = selected.first()->text(0);
|
||||||
|
m_projectSettings->setDashboardProjectName(projectName);
|
||||||
updateUi();
|
updateUi();
|
||||||
|
AxivionPlugin::fetchProjectInfo(projectName);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AxivionProjectSettingsWidget::unlinkProject()
|
void AxivionProjectSettingsWidget::unlinkProject()
|
||||||
|
|||||||
@@ -9,6 +9,8 @@
|
|||||||
#include <utils/processenums.h>
|
#include <utils/processenums.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
|
#include <QUrl>
|
||||||
|
|
||||||
using namespace Utils;
|
using namespace Utils;
|
||||||
|
|
||||||
namespace Axivion::Internal {
|
namespace Axivion::Internal {
|
||||||
@@ -27,6 +29,10 @@ QString AxivionQuery::toString() const
|
|||||||
return {};
|
return {};
|
||||||
case DashboardInfo:
|
case DashboardInfo:
|
||||||
return query;
|
return query;
|
||||||
|
case ProjectInfo:
|
||||||
|
QTC_ASSERT(m_parameters.size() == 1, return {});
|
||||||
|
query += "/projects/" + QUrl::toPercentEncoding(m_parameters.first());
|
||||||
|
return query;
|
||||||
}
|
}
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ namespace Axivion::Internal {
|
|||||||
class AxivionQuery
|
class AxivionQuery
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum QueryType {NoQuery, DashboardInfo};
|
enum QueryType {NoQuery, DashboardInfo, ProjectInfo};
|
||||||
explicit AxivionQuery(QueryType type, const QStringList ¶meters = {});
|
explicit AxivionQuery(QueryType type, const QStringList ¶meters = {});
|
||||||
|
|
||||||
QString toString() const;
|
QString toString() const;
|
||||||
|
|||||||
@@ -70,6 +70,124 @@ static std::pair<BaseResult, QJsonDocument> prehandleHeaderAndBody(const QByteAr
|
|||||||
return {result, doc};
|
return {result, doc};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static User::UserType userTypeForString(const QString &type)
|
||||||
|
{
|
||||||
|
if (type == "DASHBOARD_USER")
|
||||||
|
return User::Dashboard;
|
||||||
|
if (type == "VIRTUAL_USER")
|
||||||
|
return User::Virtual;
|
||||||
|
return User::Unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
static User userFromJson(const QJsonObject &object)
|
||||||
|
{
|
||||||
|
User result;
|
||||||
|
if (object.isEmpty()) {
|
||||||
|
result.error = "Not a user object.";
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
result.name = object.value("name").toString();
|
||||||
|
result.displayName = object.value("displayName").toString();
|
||||||
|
result.type = userTypeForString(object.value("type").toString());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static QList<User> usersFromJson(const QJsonArray &array)
|
||||||
|
{
|
||||||
|
QList<User> result;
|
||||||
|
for (const QJsonValue &value : array) {
|
||||||
|
User user = userFromJson(value.toObject());
|
||||||
|
if (!user.error.isEmpty()) // add this error to result.error?
|
||||||
|
continue;
|
||||||
|
result.append(user);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static IssueCount issueCountFromJson(const QJsonObject &object)
|
||||||
|
{
|
||||||
|
IssueCount result;
|
||||||
|
if (object.isEmpty()) {
|
||||||
|
result.error = "Not an issue count object.";
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
result.added = object.value("Added").toInt();
|
||||||
|
result.removed = object.value("Removed").toInt();
|
||||||
|
result.total = object.value("Total").toInt();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static QList<IssueCount> issueCountsFromJson(const QJsonObject &object)
|
||||||
|
{
|
||||||
|
QList<IssueCount> result;
|
||||||
|
|
||||||
|
const QStringList keys = object.keys();
|
||||||
|
for (const QString &k : keys) {
|
||||||
|
IssueCount issue = issueCountFromJson(object.value(k).toObject());
|
||||||
|
if (!issue.error.isEmpty()) // add this error to result.error?
|
||||||
|
continue;
|
||||||
|
issue.issueKind = k;
|
||||||
|
result.append(issue);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ResultVersion versionFromJson(const QJsonObject &object)
|
||||||
|
{
|
||||||
|
ResultVersion result;
|
||||||
|
if (object.isEmpty()) {
|
||||||
|
result.error = "Not a version object.";
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
const QJsonValue issuesValue = object.value("issueCounts");
|
||||||
|
if (!issuesValue.isObject()) {
|
||||||
|
result.error = "Not an object (issueCounts).";
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
result.issueCounts = issueCountsFromJson(issuesValue.toObject());
|
||||||
|
result.timeStamp = object.value("date").toString();
|
||||||
|
result.name = object.value("name").toString();
|
||||||
|
result.linesOfCode = object.value("linesOfCode").toInt();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static QList<ResultVersion> versionsFromJson(const QJsonArray &array)
|
||||||
|
{
|
||||||
|
QList<ResultVersion> result;
|
||||||
|
for (const QJsonValue &value : array) {
|
||||||
|
ResultVersion version = versionFromJson(value.toObject());
|
||||||
|
if (!version.error.isEmpty()) // add this error to result.error?
|
||||||
|
continue;
|
||||||
|
result.append(version);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static IssueKind issueKindFromJson(const QJsonObject &object)
|
||||||
|
{
|
||||||
|
IssueKind result;
|
||||||
|
if (object.isEmpty()) {
|
||||||
|
result.error = "Not an issue kind object.";
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
result.prefix = object.value("prefix").toString();
|
||||||
|
result.niceSingular = object.value("niceSingularName").toString();
|
||||||
|
result.nicePlural = object.value("nicePluralName").toString();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static QList<IssueKind> issueKindsFromJson(const QJsonArray &array)
|
||||||
|
{
|
||||||
|
QList<IssueKind> result;
|
||||||
|
for (const QJsonValue &value : array) {
|
||||||
|
IssueKind kind = issueKindFromJson(value.toObject());
|
||||||
|
if (!kind.error.isEmpty()) // add this error to result.error?
|
||||||
|
continue;
|
||||||
|
result.append(kind);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
namespace ResultParser {
|
namespace ResultParser {
|
||||||
|
|
||||||
DashboardInfo parseDashboardInfo(const QByteArray &input)
|
DashboardInfo parseDashboardInfo(const QByteArray &input)
|
||||||
@@ -109,6 +227,43 @@ DashboardInfo parseDashboardInfo(const QByteArray &input)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ProjectInfo parseProjectInfo(const QByteArray &input)
|
||||||
|
{
|
||||||
|
ProjectInfo result;
|
||||||
|
|
||||||
|
auto [header, body] = splitHeaderAndBody(input);
|
||||||
|
auto [error, doc] = prehandleHeaderAndBody(header, body);
|
||||||
|
if (!error.error.isEmpty()) {
|
||||||
|
result.error = error.error;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QJsonObject object = doc.object();
|
||||||
|
result.name = object.value("name").toString();
|
||||||
|
|
||||||
|
const QJsonValue usersValue = object.value("users");
|
||||||
|
if (!usersValue.isArray()) {
|
||||||
|
result.error = "Malformed json response (users).";
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
result.users = usersFromJson(usersValue.toArray());
|
||||||
|
|
||||||
|
const QJsonValue versionsValue = object.value("versions");
|
||||||
|
if (!versionsValue.isArray()) {
|
||||||
|
result.error = "Malformed json response (versions).";
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
result.versions = versionsFromJson(versionsValue.toArray());
|
||||||
|
|
||||||
|
const QJsonValue issueKindsValue = object.value("issueKinds");
|
||||||
|
if (!issueKindsValue.isArray()) {
|
||||||
|
result.error = "Malformed json response (issueKinds).";
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
result.issueKinds = issueKindsFromJson(issueKindsValue.toArray());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
} // ResultParser
|
} // ResultParser
|
||||||
|
|
||||||
} // Axivion::Internal
|
} // Axivion::Internal
|
||||||
|
|||||||
@@ -27,9 +27,53 @@ public:
|
|||||||
QList<Project> projects;
|
QList<Project> projects;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class User : public BaseResult
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QString name;
|
||||||
|
QString displayName;
|
||||||
|
enum UserType { Dashboard, Virtual, Unknown } type;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IssueKind : public BaseResult
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QString prefix;
|
||||||
|
QString niceSingular;
|
||||||
|
QString nicePlural;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IssueCount : public BaseResult
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QString issueKind;
|
||||||
|
int total = 0;
|
||||||
|
int added = 0;
|
||||||
|
int removed = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ResultVersion : public BaseResult
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QString name;
|
||||||
|
QString timeStamp;
|
||||||
|
QList<IssueCount> issueCounts;
|
||||||
|
int linesOfCode = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ProjectInfo : public BaseResult
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
QString name;
|
||||||
|
QList<User> users;
|
||||||
|
QList<ResultVersion> versions;
|
||||||
|
QList<IssueKind> issueKinds;
|
||||||
|
};
|
||||||
|
|
||||||
namespace ResultParser {
|
namespace ResultParser {
|
||||||
|
|
||||||
DashboardInfo parseDashboardInfo(const QByteArray &input);
|
DashboardInfo parseDashboardInfo(const QByteArray &input);
|
||||||
|
ProjectInfo parseProjectInfo(const QByteArray &input);
|
||||||
|
|
||||||
} // ResultParser
|
} // ResultParser
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user