mirror of
https://github.com/Chatterino/chatterino2.git
synced 2024-11-21 22:24:07 +01:00
Validate info.json harder and show what's wrong
This commit is contained in:
parent
11f19ecc66
commit
e9aa136bbe
2 changed files with 79 additions and 12 deletions
|
@ -2,6 +2,7 @@
|
||||||
#include "Application.hpp"
|
#include "Application.hpp"
|
||||||
#include "controllers/commands/CommandController.hpp"
|
#include "controllers/commands/CommandController.hpp"
|
||||||
|
|
||||||
|
#include <magic_enum.hpp>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QJsonArray>
|
#include <QJsonArray>
|
||||||
#include <QJsonObject>
|
#include <QJsonObject>
|
||||||
|
@ -16,24 +17,55 @@ struct lua_State;
|
||||||
namespace chatterino {
|
namespace chatterino {
|
||||||
|
|
||||||
struct PluginMeta {
|
struct PluginMeta {
|
||||||
|
// required fields
|
||||||
QString name;
|
QString name;
|
||||||
QString description;
|
QString description;
|
||||||
QString authors;
|
QString authors;
|
||||||
QString homepage;
|
|
||||||
|
|
||||||
QString license;
|
QString license;
|
||||||
semver::version version;
|
semver::version version;
|
||||||
|
|
||||||
|
// optional
|
||||||
|
QString homepage;
|
||||||
std::vector<QString> tags;
|
std::vector<QString> tags;
|
||||||
|
|
||||||
|
bool valid{};
|
||||||
|
std::vector<QString> invalidWhy;
|
||||||
|
|
||||||
explicit PluginMeta(const QJsonObject &obj)
|
explicit PluginMeta(const QJsonObject &obj)
|
||||||
: name(obj.value("name").toString("A Plugin with no name"))
|
: homepage(obj.value("homepage").toString(""))
|
||||||
, description(obj.value("description").toString("Nothing here"))
|
|
||||||
, authors(
|
|
||||||
obj.value("authors").toString("[please tell me who made this]"))
|
|
||||||
, homepage(obj.value("homepage").toString("[https://example.com]"))
|
|
||||||
, license(obj.value("license").toString("[unknown]"))
|
|
||||||
{
|
{
|
||||||
|
auto nameObj = obj.value("name");
|
||||||
|
if (!nameObj.isString())
|
||||||
|
{
|
||||||
|
this->invalidWhy.emplace_back("name is not a string");
|
||||||
|
this->valid = false;
|
||||||
|
}
|
||||||
|
this->name = nameObj.toString();
|
||||||
|
|
||||||
|
auto descrObj = obj.value("description");
|
||||||
|
if (!descrObj.isString())
|
||||||
|
{
|
||||||
|
this->invalidWhy.emplace_back("description is not a string");
|
||||||
|
this->valid = false;
|
||||||
|
}
|
||||||
|
this->description = descrObj.toString();
|
||||||
|
|
||||||
|
auto authorsObj = obj.value("authors");
|
||||||
|
if (!authorsObj.isString())
|
||||||
|
{
|
||||||
|
this->invalidWhy.emplace_back("description is not a string");
|
||||||
|
this->valid = false;
|
||||||
|
}
|
||||||
|
this->authors = authorsObj.toString();
|
||||||
|
|
||||||
|
auto licenseObj = obj.value("license");
|
||||||
|
if (!licenseObj.isString())
|
||||||
|
{
|
||||||
|
this->invalidWhy.emplace_back("license is not a string");
|
||||||
|
this->valid = false;
|
||||||
|
}
|
||||||
|
this->license = licenseObj.toString();
|
||||||
|
|
||||||
auto v = semver::from_string_noexcept(
|
auto v = semver::from_string_noexcept(
|
||||||
obj.value("version").toString().toStdString());
|
obj.value("version").toString().toStdString());
|
||||||
if (v.has_value())
|
if (v.has_value())
|
||||||
|
@ -42,14 +74,38 @@ struct PluginMeta {
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
this->invalidWhy.emplace_back("unable to parse version");
|
||||||
|
this->valid = false;
|
||||||
this->version = semver::version(0, 0, 0);
|
this->version = semver::version(0, 0, 0);
|
||||||
description.append("\nWarning: invalid version. Use semver.");
|
|
||||||
}
|
}
|
||||||
for (const auto &t : obj.value("tags").toArray())
|
auto tagsObj = obj.value("tags");
|
||||||
|
if (!tagsObj.isUndefined())
|
||||||
{
|
{
|
||||||
|
if (!tagsObj.isArray())
|
||||||
|
{
|
||||||
|
this->invalidWhy.emplace_back("tags is not an array");
|
||||||
|
this->valid = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto tagsArr = tagsObj.toArray();
|
||||||
|
for (int i = 0; i < tagsArr.size(); i++)
|
||||||
|
{
|
||||||
|
const auto &t = tagsArr.at(i);
|
||||||
|
if (!t.isString())
|
||||||
|
{
|
||||||
|
this->invalidWhy.push_back(
|
||||||
|
QString("tags element #%1 is not a string (it is a %2)")
|
||||||
|
.arg(i)
|
||||||
|
.arg(QString::fromStdString(
|
||||||
|
std::string(magic_enum::enum_name(t.type())))));
|
||||||
|
this->valid = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
this->tags.push_back(t.toString());
|
this->tags.push_back(t.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class Plugin
|
class Plugin
|
||||||
|
|
|
@ -101,7 +101,18 @@ bool PluginController::tryLoadFromDir(const QDir &pluginDir)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
this->load(index, pluginDir, PluginMeta(doc.object()));
|
auto meta = PluginMeta(doc.object());
|
||||||
|
if (!meta.invalidWhy.empty())
|
||||||
|
{
|
||||||
|
qCDebug(chatterinoLua)
|
||||||
|
<< "Plugin from" << pluginDir << "is invalid because:";
|
||||||
|
for (const auto &why : meta.invalidWhy)
|
||||||
|
{
|
||||||
|
qCDebug(chatterinoLua) << "- " << why;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
this->load(index, pluginDir, meta);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue