Implement gradle spec reader/writer
This commit is contained in:
parent
71575a5022
commit
8a56ab6780
@ -427,6 +427,9 @@ SET(MULTIMC_SOURCES
|
||||
# RW lock protected map
|
||||
logic/RWStorage.h
|
||||
|
||||
# A variable that has an implicit default value and keeps track of changes
|
||||
logic/DefaultVariable.h
|
||||
|
||||
# network stuffs
|
||||
logic/net/NetAction.h
|
||||
logic/net/MD5EtagDownload.h
|
||||
@ -493,6 +496,7 @@ SET(MULTIMC_SOURCES
|
||||
logic/OneSixInstance_p.h
|
||||
|
||||
# OneSix version json infrastructure
|
||||
logic/minecraft/GradleSpecifier.h
|
||||
logic/minecraft/InstanceVersion.cpp
|
||||
logic/minecraft/InstanceVersion.h
|
||||
logic/minecraft/JarMod.cpp
|
||||
|
35
logic/DefaultVariable.h
Normal file
35
logic/DefaultVariable.h
Normal file
@ -0,0 +1,35 @@
|
||||
#pragma once
|
||||
|
||||
template <typename T>
|
||||
class DefaultVariable
|
||||
{
|
||||
public:
|
||||
DefaultVariable(const T & value)
|
||||
{
|
||||
defaultValue = value;
|
||||
}
|
||||
DefaultVariable<T> & operator =(const T & value)
|
||||
{
|
||||
currentValue = value;
|
||||
is_default = currentValue == defaultValue;
|
||||
is_explicit = true;
|
||||
return *this;
|
||||
}
|
||||
operator const T &() const
|
||||
{
|
||||
return is_default ? defaultValue : currentValue;
|
||||
}
|
||||
bool isDefault() const
|
||||
{
|
||||
return is_default;
|
||||
}
|
||||
bool isExplicit() const
|
||||
{
|
||||
return is_explicit;
|
||||
}
|
||||
private:
|
||||
T currentValue;
|
||||
T defaultValue;
|
||||
bool is_default = true;
|
||||
bool is_explicit = false;
|
||||
};
|
@ -331,7 +331,29 @@ QSet<FTBRecord> InstanceList::discoverFTBInstances()
|
||||
continue;
|
||||
record.name = attrs.value("name").toString();
|
||||
record.logo = attrs.value("logo").toString();
|
||||
record.mcVersion = attrs.value("mcVersion").toString();
|
||||
auto customVersions = attrs.value("customMCVersions");
|
||||
if(!customVersions.isNull())
|
||||
{
|
||||
QMap<QString, QString> versionMatcher;
|
||||
QString customVersionsStr = customVersions.toString();
|
||||
QStringList list = customVersionsStr.split(';');
|
||||
for(auto item: list)
|
||||
{
|
||||
auto segment = item.split('^');
|
||||
if(segment.size() != 2)
|
||||
{
|
||||
QLOG_ERROR() << "FTB: Segment of size < 2 in " << customVersionsStr;
|
||||
continue;
|
||||
}
|
||||
versionMatcher[segment[0]] = segment[1];
|
||||
}
|
||||
auto actualVersion = attrs.value("version").toString();
|
||||
record.mcVersion = versionMatcher[actualVersion];
|
||||
}
|
||||
else
|
||||
{
|
||||
record.mcVersion = attrs.value("mcVersion").toString();
|
||||
}
|
||||
record.description = attrs.value("description").toString();
|
||||
records.insert(record);
|
||||
}
|
||||
|
83
logic/minecraft/GradleSpecifier.h
Normal file
83
logic/minecraft/GradleSpecifier.h
Normal file
@ -0,0 +1,83 @@
|
||||
#pragma once
|
||||
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include "logic/DefaultVariable.h"
|
||||
|
||||
struct GradleSpecifier
|
||||
{
|
||||
GradleSpecifier()
|
||||
{
|
||||
m_valid = false;
|
||||
}
|
||||
GradleSpecifier(QString value)
|
||||
{
|
||||
operator=(value);
|
||||
}
|
||||
GradleSpecifier & operator =(const QString & value)
|
||||
{
|
||||
/*
|
||||
org.gradle.test.classifiers : service : 1.0 : jdk15 @ jar
|
||||
DEBUG 0 "org.gradle.test.classifiers:service:1.0:jdk15@jar"
|
||||
DEBUG 1 "org.gradle.test.classifiers"
|
||||
DEBUG 2 "service"
|
||||
DEBUG 3 "1.0"
|
||||
DEBUG 4 ":jdk15"
|
||||
DEBUG 5 "jdk15"
|
||||
DEBUG 6 "@jar"
|
||||
DEBUG 7 "jar"
|
||||
*/
|
||||
QRegExp matcher("([^:@]+):([^:@]+):([^:@]+)" "(:([^:@]+))?" "(@([^:@]+))?");
|
||||
m_valid = matcher.exactMatch(value);
|
||||
auto elements = matcher.capturedTexts();
|
||||
groupId = elements[1];
|
||||
artifactId = elements[2];
|
||||
version = elements[3];
|
||||
classifier = elements[5];
|
||||
if(!elements[7].isEmpty())
|
||||
{
|
||||
extension = elements[7];
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
operator QString() const
|
||||
{
|
||||
if(!m_valid)
|
||||
return "INVALID";
|
||||
QString retval = groupId + ":" + artifactId + ":" + version;
|
||||
if(!classifier.isEmpty())
|
||||
{
|
||||
retval += ":" + classifier;
|
||||
}
|
||||
if(extension.isExplicit())
|
||||
{
|
||||
retval += "@" + extension;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
QString toPath() const
|
||||
{
|
||||
if(!m_valid)
|
||||
return "INVALID";
|
||||
QString path = groupId;
|
||||
path.replace('.', '/');
|
||||
path += '/' + artifactId + '/' + version + '/' + artifactId + '-' + version;
|
||||
if(!classifier.isEmpty())
|
||||
{
|
||||
path += "-" + classifier;
|
||||
}
|
||||
path += "." + extension;
|
||||
return path;
|
||||
}
|
||||
bool valid()
|
||||
{
|
||||
return m_valid;
|
||||
}
|
||||
private:
|
||||
QString groupId;
|
||||
QString artifactId;
|
||||
QString version;
|
||||
QString classifier;
|
||||
DefaultVariable<QString> extension = DefaultVariable<QString>("jar");
|
||||
bool m_valid = false;
|
||||
};
|
@ -65,7 +65,10 @@ void OneSixLibrary::finalize()
|
||||
m_decentname = parts[1];
|
||||
m_decentversion = minVersion = parts[2];
|
||||
m_storage_path = relative;
|
||||
m_download_url = m_base_url + relative;
|
||||
if(m_base_url.isEmpty())
|
||||
m_download_url = QString("https://" + URLConstants::LIBRARY_BASE) + relative;
|
||||
else
|
||||
m_download_url = m_base_url + relative;
|
||||
|
||||
if (m_rules.empty())
|
||||
{
|
||||
|
@ -13,20 +13,20 @@ RawLibraryPtr RawLibrary::fromJson(const QJsonObject &libObj, const QString &fil
|
||||
}
|
||||
out->m_name = libObj.value("name").toString();
|
||||
|
||||
auto readString = [libObj, filename](const QString & key, QString & variable)
|
||||
auto readString = [libObj, filename](const QString & key, QString & variable) -> bool
|
||||
{
|
||||
if (libObj.contains(key))
|
||||
if (!libObj.contains(key))
|
||||
return false;
|
||||
QJsonValue val = libObj.value(key);
|
||||
|
||||
if (!val.isString())
|
||||
{
|
||||
QJsonValue val = libObj.value(key);
|
||||
if (!val.isString())
|
||||
{
|
||||
QLOG_WARN() << key << "is not a string in" << filename << "(skipping)";
|
||||
}
|
||||
else
|
||||
{
|
||||
variable = val.toString();
|
||||
}
|
||||
QLOG_WARN() << key << "is not a string in" << filename << "(skipping)";
|
||||
return false;
|
||||
}
|
||||
|
||||
variable = val.toString();
|
||||
return true;
|
||||
};
|
||||
|
||||
readString("url", out->m_base_url);
|
||||
|
@ -28,10 +28,11 @@ public: /* methods */
|
||||
|
||||
public: /* data */
|
||||
QString m_name;
|
||||
QString m_base_url = "https://" + URLConstants::LIBRARY_BASE;
|
||||
QString m_base_url;
|
||||
|
||||
/// type hint - modifies how the library is treated
|
||||
QString m_hint;
|
||||
/// absolute URL. takes precedence over m_download_path, if defined
|
||||
/// DEPRECATED: absolute URL. takes precedence over m_download_path, if defined
|
||||
QString m_absolute_url;
|
||||
|
||||
bool applyExcludes = false;
|
||||
|
@ -22,6 +22,7 @@ endmacro()
|
||||
# Tests START #
|
||||
|
||||
add_unit_test(pathutils tst_pathutils.cpp)
|
||||
add_unit_test(gradlespecifier tst_gradlespecifier.cpp)
|
||||
add_unit_test(userutils tst_userutils.cpp)
|
||||
add_unit_test(inifile tst_inifile.cpp)
|
||||
add_unit_test(UpdateChecker tst_UpdateChecker.cpp)
|
||||
|
77
tests/tst_gradlespecifier.cpp
Normal file
77
tests/tst_gradlespecifier.cpp
Normal file
@ -0,0 +1,77 @@
|
||||
#include <QTest>
|
||||
#include "TestUtil.h"
|
||||
|
||||
#include "logic/minecraft/GradleSpecifier.h"
|
||||
|
||||
class GradleSpecifierTest : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
private
|
||||
slots:
|
||||
void initTestCase()
|
||||
{
|
||||
|
||||
}
|
||||
void cleanupTestCase()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void test_Positive_data()
|
||||
{
|
||||
QTest::addColumn<QString>("through");
|
||||
|
||||
QTest::newRow("3 parter") << "org.gradle.test.classifiers:service:1.0";
|
||||
QTest::newRow("classifier") << "org.gradle.test.classifiers:service:1.0:jdk15";
|
||||
QTest::newRow("jarextension") << "org.gradle.test.classifiers:service:1.0@jar";
|
||||
QTest::newRow("jarboth") << "org.gradle.test.classifiers:service:1.0:jdk15@jar";
|
||||
QTest::newRow("packxz") << "org.gradle.test.classifiers:service:1.0:jdk15@jar.pack.xz";
|
||||
}
|
||||
void test_Positive()
|
||||
{
|
||||
QFETCH(QString, through);
|
||||
|
||||
QString converted = GradleSpecifier(through);
|
||||
|
||||
QCOMPARE(converted, through);
|
||||
}
|
||||
|
||||
void test_Path_data()
|
||||
{
|
||||
QTest::addColumn<QString>("spec");
|
||||
QTest::addColumn<QString>("expected");
|
||||
|
||||
QTest::newRow("3 parter") << "group.id:artifact:1.0" << "group/id/artifact/1.0/artifact-1.0.jar";
|
||||
QTest::newRow("doom") << "id.software:doom:1.666:demons@wad" << "id/software/doom/1.666/doom-1.666-demons.wad";
|
||||
}
|
||||
void test_Path()
|
||||
{
|
||||
QFETCH(QString, spec);
|
||||
QFETCH(QString, expected);
|
||||
|
||||
QString converted = GradleSpecifier(spec).toPath();
|
||||
|
||||
QCOMPARE(converted, expected);
|
||||
}
|
||||
void test_Negative_data()
|
||||
{
|
||||
QTest::addColumn<QString>("input");
|
||||
|
||||
QTest::newRow("too many :") << "org:gradle.test:class:::ifiers:service:1.0::";
|
||||
QTest::newRow("nonsense") << "I like turtles";
|
||||
QTest::newRow("empty string") << "";
|
||||
QTest::newRow("missing version") << "herp.derp:artifact";
|
||||
}
|
||||
void test_Negative()
|
||||
{
|
||||
QFETCH(QString, input);
|
||||
|
||||
GradleSpecifier spec(input);
|
||||
QVERIFY(!spec.valid());
|
||||
QCOMPARE(spec.operator QString(), QString("INVALID"));
|
||||
}
|
||||
};
|
||||
|
||||
QTEST_GUILESS_MAIN_MULTIMC(GradleSpecifierTest)
|
||||
|
||||
#include "tst_gradlespecifier.moc"
|
Loading…
Reference in New Issue
Block a user