Commit bdb45718 authored by Daniel Mensinger's avatar Daniel Mensinger
Browse files

meson: initial rewriter stub

parent def23121
......@@ -13,12 +13,17 @@ set(mesonbuilder_SRCS
mintro/mesontargets.cpp
mintro/mesontests.cpp
rewriter/mesonactionbase.cpp
rewriter/mesonkwargsinfo.cpp
rewriter/mesonrewriterjob.cpp
settings/mesonadvancedsettings.cpp
settings/mesonconfigpage.cpp
settings/mesonlisteditor.cpp
settings/mesonnewbuilddir.cpp
settings/mesonoptionbaseview.cpp
settings/mesonoptionsview.cpp
settings/mesonrewriterpage.cpp
)
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
......@@ -30,6 +35,7 @@ ki18n_wrap_ui(mesonbuilder_SRCS
settings/mesonnewbuilddir.ui
settings/mesonoptionbaseview.ui
settings/mesonoptionsview.ui
settings/mesonrewriterpage.ui
)
ecm_qt_declare_logging_category(mesonbuilder_SRCS
HEADER debug.h
......
......@@ -27,6 +27,7 @@
#include "mintro/mesontargets.h"
#include "settings/mesonconfigpage.h"
#include "settings/mesonnewbuilddir.h"
#include "settings/mesonrewriterpage.h"
#include <interfaces/icore.h>
#include <interfaces/iproject.h>
......@@ -477,15 +478,18 @@ Path MesonManager::findMeson() const
ConfigPage* MesonManager::perProjectConfigPage(int number, const ProjectConfigOptions& options, QWidget* parent)
{
if (number == 0) {
switch (number) {
case 0:
return new MesonConfigPage(this, options.project, parent);
case 1:
return new MesonRewriterPage(this, options.project, parent);
}
return nullptr;
}
int MesonManager::perProjectConfigPages() const
{
return 1;
return 2;
}
#include "mesonmanager.moc"
/* This file is part of KDevelop
Copyright 2019 Daniel Mensinger <daniel@mensinger-ka.de>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "mesonactionbase.h"
MesonRewriterActionBase::MesonRewriterActionBase() {}
MesonRewriterActionBase::~MesonRewriterActionBase() {}
void MesonRewriterActionBase::parseResult(QJsonObject) {}
/* This file is part of KDevelop
Copyright 2019 Daniel Mensinger <daniel@mensinger-ka.de>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#pragma once
#include <memory>
#include <QJsonObject>
class MesonRewriterActionBase;
using MesonRewriterActionPtr = std::shared_ptr<MesonRewriterActionBase>;
class MesonRewriterActionBase
{
public:
explicit MesonRewriterActionBase();
virtual ~MesonRewriterActionBase();
virtual QJsonObject command() = 0;
virtual void parseResult(QJsonObject);
};
/* This file is part of KDevelop
Copyright 2019 Daniel Mensinger <daniel@mensinger-ka.de>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "mesonkwargsinfo.h"
#include "debug.h"
MesonKWARGSInfo::MesonKWARGSInfo(MesonKWARGSInfo::Function fn, QString id)
: m_func(fn)
, m_id(id)
{
}
QJsonObject MesonKWARGSInfo::command()
{
QJsonObject res;
auto func2str = [](Function fn) -> QString {
switch (fn) {
case PROJECT:
return QStringLiteral("project");
case TARGET:
return QStringLiteral("target");
case DEPENDENCY:
return QStringLiteral("dependency");
}
return QStringLiteral("ERROR");
};
res[QStringLiteral("type")] = QStringLiteral("kwargs");
res[QStringLiteral("function")] = func2str(m_func);
res[QStringLiteral("id")] = m_id;
res[QStringLiteral("operation")] = QStringLiteral("info");
m_infoID = func2str(m_func) + QStringLiteral("#") + m_id;
return res;
}
void MesonKWARGSInfo::parseResult(QJsonObject data)
{
if (!data[QStringLiteral("kwargs")].isObject()) {
qCWarning(KDEV_Meson) << "REWRITR: Failed to parse rewriter result";
return;
}
QJsonObject kwargs = data[QStringLiteral("kwargs")].toObject();
if (!kwargs[m_infoID].isObject()) {
qCWarning(KDEV_Meson) << "REWRITR: Failed to extract info data from object";
return;
}
m_result = kwargs[m_infoID].toObject();
}
MesonKWARGSInfo::Function MesonKWARGSInfo::function() const
{
return m_func;
}
QString MesonKWARGSInfo::id() const
{
return m_id;
}
QJsonObject MesonKWARGSInfo::result() const
{
return m_result;
}
QString MesonKWARGSInfo::getString(QString kwarg) const
{
return m_result[kwarg].toString();
}
// Getters for Project
QString MesonKWARGSProjectInfo::mesonVersion() const
{
return getString(QStringLiteral("meson_version"));
}
QString MesonKWARGSProjectInfo::license() const
{
return getString(QStringLiteral("license"));
}
QString MesonKWARGSProjectInfo::subprojectDir() const
{
return getString(QStringLiteral("subproject_dir"));
}
QString MesonKWARGSProjectInfo::version() const
{
return getString(QStringLiteral("version"));
}
// Constructors
MesonKWARGSProjectInfo::MesonKWARGSProjectInfo()
: MesonKWARGSInfo(PROJECT, QStringLiteral("/"))
{
}
MesonKWARGSTargetInfo::MesonKWARGSTargetInfo(QString id)
: MesonKWARGSInfo(TARGET, id)
{
}
MesonKWARGSDependencyInfo::MesonKWARGSDependencyInfo(QString id)
: MesonKWARGSInfo(DEPENDENCY, id)
{
}
// Destructors
MesonKWARGSInfo::~MesonKWARGSInfo() {}
MesonKWARGSProjectInfo::~MesonKWARGSProjectInfo() {}
MesonKWARGSTargetInfo::~MesonKWARGSTargetInfo() {}
MesonKWARGSDependencyInfo::~MesonKWARGSDependencyInfo() {}
/* This file is part of KDevelop
Copyright 2019 Daniel Mensinger <daniel@mensinger-ka.de>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#pragma once
#include "mesonactionbase.h"
#include <QHash>
class MesonKWARGSInfo;
class MesonKWARGSProjectInfo;
class MesonKWARGSTargetInfo;
class MesonKWARGSDependencyInfo;
using MesonKWARGSInfoPtr = std::shared_ptr<MesonKWARGSInfo>;
using MesonKWARGSProjectInfoPtr = std::shared_ptr<MesonKWARGSProjectInfo>;
using MesonKWARGSTargetInfoPtr = std::shared_ptr<MesonKWARGSTargetInfo>;
using MesonKWARGSDependencyInfoPtr = std::shared_ptr<MesonKWARGSDependencyInfo>;
class MesonKWARGSInfo : public MesonRewriterActionBase
{
public:
enum Function { PROJECT, TARGET, DEPENDENCY };
public:
explicit MesonKWARGSInfo(Function fn, QString id);
virtual ~MesonKWARGSInfo();
QJsonObject command() override;
void parseResult(QJsonObject data) override;
Function function() const;
QString id() const;
QJsonObject result() const;
QString getString(QString kwarg) const;
private:
Function m_func;
QString m_id;
QJsonObject m_result;
QString m_infoID;
};
class MesonKWARGSProjectInfo : public MesonKWARGSInfo
{
public:
explicit MesonKWARGSProjectInfo();
virtual ~MesonKWARGSProjectInfo();
QString mesonVersion() const;
QString license() const;
QString subprojectDir() const;
QString version() const;
};
class MesonKWARGSTargetInfo : public MesonKWARGSInfo
{
public:
explicit MesonKWARGSTargetInfo(QString id);
virtual ~MesonKWARGSTargetInfo();
// TODO some accessors similar to MesonKWARGSProjectInfo
};
class MesonKWARGSDependencyInfo : public MesonKWARGSInfo
{
public:
explicit MesonKWARGSDependencyInfo(QString id);
virtual ~MesonKWARGSDependencyInfo();
// TODO some accessors similar to MesonKWARGSProjectInfo
};
/* This file is part of KDevelop
Copyright 2019 Daniel Mensinger <daniel@mensinger-ka.de>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "mesonrewriterjob.h"
#include "mesonconfig.h"
#include "interfaces/iproject.h"
#include "util/path.h"
#include <KLocalizedString>
#include <KProcess>
#include <QJsonArray>
#include <QJsonDocument>
#include <QTemporaryFile>
#include <QtConcurrentRun>
#include "debug.h"
using namespace KDevelop;
MesonRewriterJob::MesonRewriterJob(IProject* project, QVector<MesonRewriterActionPtr> actions, QObject* parent)
: KJob(parent)
, m_project(project)
, m_actions(actions)
{
connect(&m_futureWatcher, &QFutureWatcher<QString>::finished, this, &MesonRewriterJob::finished);
}
QString MesonRewriterJob::execute()
{
QJsonArray command;
for (auto& i : m_actions) {
command.append(i->command());
}
QTemporaryFile tempFile;
tempFile.setAutoRemove(false);
if (!tempFile.open()) {
return i18n("Failed to create a temorary file");
}
QJsonDocument doc(command);
tempFile.write(doc.toJson());
tempFile.flush();
Meson::BuildDir buildDir = Meson::currentBuildDir(m_project);
KProcess proc(this);
proc.setWorkingDirectory(m_project->path().toLocalFile());
proc.setOutputChannelMode(KProcess::SeparateChannels);
proc.setProgram(buildDir.mesonExecutable.toLocalFile());
proc << QStringLiteral("rewrite") << QStringLiteral("command") << tempFile.fileName();
int ret = proc.execute();
if (ret != 0) {
return i18n("%1 returned %2", proc.program().join(QChar::fromLatin1(' ')), ret);
}
auto rawData = proc.readAllStandardError();
if (rawData.isEmpty()) {
return QString();
}
QJsonParseError error;
QJsonDocument result = QJsonDocument::fromJson(rawData, &error);
if (error.error) {
return i18n("JSON parser error: %1", error.errorString());
}
if (!result.isObject()) {
return i18n("The rewriter output of '%1' is not an object", proc.program().join(QChar::fromLatin1(' ')));
}
for (auto& i : m_actions) {
i->parseResult(result.object());
}
return QString();
}
void MesonRewriterJob::finished()
{
QString result = m_futureWatcher.result();
if (!result.isEmpty()) {
qCWarning(KDEV_Meson) << "REWRITER " << result;
setError(true);
setErrorText(result);
emitResult();
return;
}
qCDebug(KDEV_Meson) << "REWRITER: Meson rewriter job finished";
emitResult();
}
bool MesonRewriterJob::doKill()
{
if (m_futureWatcher.isRunning()) {
m_futureWatcher.cancel();
}
return true;
}
void MesonRewriterJob::start()
{
auto future = QtConcurrent::run(this, &MesonRewriterJob::execute);
m_futureWatcher.setFuture(future);
}
/* This file is part of KDevelop
Copyright 2019 Daniel Mensinger <daniel@mensinger-ka.de>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#pragma once
#include "mesonactionbase.h"
#include <KJob>
#include <QFutureWatcher>
#include <QVector>
namespace KDevelop
{
class IProject;
}
class MesonRewriterJob : public KJob
{
Q_OBJECT
public:
explicit MesonRewriterJob(KDevelop::IProject* project, QVector<MesonRewriterActionPtr> actions, QObject* parent);
void start() override;
bool doKill() override;
private:
QString execute();
void finished();
private:
KDevelop::IProject* m_project = nullptr;
QVector<MesonRewriterActionPtr> m_actions;
QFutureWatcher<QString> m_futureWatcher;
};
/* This file is part of KDevelop
Copyright 2019 Daniel Mensinger <daniel@mensinger-ka.de>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "mesonrewriterpage.h"
#include "mesonconfig.h"
#include "mesonmanager.h"
#include "mintro/mesonintrospectjob.h"
#include "mintro/mesonprojectinfo.h"
#include "rewriter/mesonkwargsinfo.h"
#include "rewriter/mesonrewriterjob.h"
#include "ui_mesonrewriterpage.h"
#include <interfaces/iplugin.h>
#include <interfaces/iproject.h>
#include <util/executecompositejob.h>
#include <KColorScheme>
#include <QIcon>
#include <debug.h>
using namespace KDevelop;
class JobDeleter
{
public:
explicit JobDeleter(QList<KJob*> jobs)
: m_jobs(jobs)
{
}
~JobDeleter()
{
for (KJob* i : m_jobs) {
delete i;
}
}
private:
QList<KJob*> m_jobs;
};
MesonRewriterPage::MesonRewriterPage(IPlugin* plugin, IProject* project, QWidget* parent)
: ConfigPage(plugin, nullptr, parent)
, m_project(project)
{
Q_ASSERT(m_project);
m_ui = new Ui::MesonRewriterPage;
m_ui->setupUi(this);
reset();
}
void MesonRewriterPage::setWidgetsDisabled(bool disabled)
{
m_ui->c_tabs->setDisabled(disabled);
}
void MesonRewriterPage::checkStatus()
{
// Get the config build dir status
auto setStatus = [this](QString const& msg, int color) -> void {
KColorScheme scheme(QPalette::Normal);
KColorScheme::ForegroundRole role;
switch (color) {
case 0:
role = KColorScheme::PositiveText;
setDisabled(false);
break;
case 1:
role = KColorScheme::NeutralText;
setDisabled(true);
break;
case 2:
default:
role = KColorScheme::NegativeText;