Validate info.json harder and show what's wrong

This commit is contained in:
Mm2PL 2023-02-07 00:34:03 +01:00
parent 11f19ecc66
commit e9aa136bbe
No known key found for this signature in database
GPG key ID: 94AC9B80EFA15ED9
2 changed files with 79 additions and 12 deletions

View file

@ -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

View file

@ -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;
} }