1 parent
ebf8ff7869
commit
41599fa82f
67 files changed
+8775
-4
No files matched your search
@@ -0,0 +1,204 @@
|
||||
#include "fixtures.h"
|
||||
|
||||
#include "minecraftversion.h"
|
||||
|
||||
#include <QBuffer>
|
||||
#include <QCryptographicHash>
|
||||
#include <QDir>
|
||||
#include <QDirIterator>
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
#include <QProcess>
|
||||
#include <QTemporaryDir>
|
||||
#include <QtCore/private/qzipreader_p.h>
|
||||
#include <QtCore/private/qzipwriter_p.h>
|
||||
|
||||
QString Fixtures::path(const QString &relative)
|
||||
{
|
||||
return QStringLiteral(BILAUNCHER_FIXTURES_DIR) + u'/' + relative;
|
||||
}
|
||||
|
||||
QByteArray Fixtures::read(const QString &relative)
|
||||
{
|
||||
QFile file(path(relative));
|
||||
if (!file.open(QIODevice::ReadOnly))
|
||||
qFatal("Нет фикстуры %s", qPrintable(file.fileName()));
|
||||
return file.readAll();
|
||||
}
|
||||
|
||||
QJsonObject Fixtures::readJson(const QString &relative)
|
||||
{
|
||||
return QJsonDocument::fromJson(read(relative)).object();
|
||||
}
|
||||
|
||||
QString Fixtures::otherOsName()
|
||||
{
|
||||
return VersionLoader::osName() == QLatin1String("windows") ? QStringLiteral("linux")
|
||||
: QStringLiteral("windows");
|
||||
}
|
||||
|
||||
QByteArray Fixtures::applyTemplate(QByteArray text)
|
||||
{
|
||||
text.replace("%OS%", VersionLoader::osName().toUtf8());
|
||||
text.replace("%OTHER%", otherOsName().toUtf8());
|
||||
text.replace("%ARCH%", VersionLoader::osArch().toUtf8());
|
||||
text.replace("%NATIVE%", VersionLoader::nativeClassifier().toUtf8());
|
||||
return text;
|
||||
}
|
||||
|
||||
QByteArray Fixtures::readTemplate(const QString &relative)
|
||||
{
|
||||
return applyTemplate(read(relative));
|
||||
}
|
||||
|
||||
bool Fixtures::write(const QString &filePath, const QByteArray &data)
|
||||
{
|
||||
QDir().mkpath(QFileInfo(filePath).absolutePath());
|
||||
QFile file(filePath);
|
||||
if (!file.open(QIODevice::WriteOnly | QIODevice::Truncate))
|
||||
return false;
|
||||
return file.write(data) == data.size();
|
||||
}
|
||||
|
||||
bool Fixtures::writeJson(const QString &filePath, const QJsonObject &object)
|
||||
{
|
||||
return write(filePath, QJsonDocument(object).toJson(QJsonDocument::Indented));
|
||||
}
|
||||
|
||||
QByteArray Fixtures::readFile(const QString &filePath)
|
||||
{
|
||||
QFile file(filePath);
|
||||
if (!file.open(QIODevice::ReadOnly))
|
||||
return {};
|
||||
return file.readAll();
|
||||
}
|
||||
|
||||
QJsonObject Fixtures::readJsonFile(const QString &filePath)
|
||||
{
|
||||
return QJsonDocument::fromJson(readFile(filePath)).object();
|
||||
}
|
||||
|
||||
QByteArray Fixtures::zipBytes(const QMap<QString, QByteArray> &entries)
|
||||
{
|
||||
QBuffer buffer;
|
||||
buffer.open(QIODevice::WriteOnly);
|
||||
{
|
||||
QZipWriter writer(&buffer);
|
||||
writer.setCompressionPolicy(QZipWriter::AutoCompress);
|
||||
for (auto it = entries.cbegin(); it != entries.cend(); ++it) {
|
||||
if (it.key().endsWith(u'/'))
|
||||
writer.addDirectory(it.key());
|
||||
else
|
||||
writer.addFile(it.key(), it.value());
|
||||
}
|
||||
writer.close();
|
||||
}
|
||||
return buffer.data();
|
||||
}
|
||||
|
||||
bool Fixtures::makeZip(const QString &zipPath, const QMap<QString, QByteArray> &entries)
|
||||
{
|
||||
return write(zipPath, zipBytes(entries));
|
||||
}
|
||||
|
||||
QStringList Fixtures::zipEntries(const QString &zipPath)
|
||||
{
|
||||
QZipReader reader(zipPath);
|
||||
QStringList result;
|
||||
for (const QZipReader::FileInfo &info : reader.fileInfoList()) {
|
||||
if (info.isFile)
|
||||
result << info.filePath;
|
||||
}
|
||||
result.sort();
|
||||
return result;
|
||||
}
|
||||
|
||||
bool Fixtures::makeTarGz(const QString &archivePath, const QMap<QString, QByteArray> &entries)
|
||||
{
|
||||
QTemporaryDir staging;
|
||||
if (!staging.isValid())
|
||||
return false;
|
||||
QStringList tops;
|
||||
for (auto it = entries.cbegin(); it != entries.cend(); ++it) {
|
||||
if (!write(staging.path() + u'/' + it.key(), it.value()))
|
||||
return false;
|
||||
const QString top = it.key().section(u'/', 0, 0);
|
||||
if (!tops.contains(top))
|
||||
tops << top;
|
||||
}
|
||||
QDir().mkpath(QFileInfo(archivePath).absolutePath());
|
||||
|
||||
QProcess tar;
|
||||
tar.setWorkingDirectory(staging.path());
|
||||
#if defined(Q_OS_WIN)
|
||||
// Системный bsdtar по полному пути: GNU tar из Git, который бывает раньше в PATH,
|
||||
// принимает «C:» за имя удалённого хоста (та же история в release.yml).
|
||||
const QString program = qEnvironmentVariable("SystemRoot") + QStringLiteral("\\System32\\tar.exe");
|
||||
#else
|
||||
const QString program = QStringLiteral("tar");
|
||||
#endif
|
||||
tar.start(program,
|
||||
QStringList{QStringLiteral("-czf"), QDir::toNativeSeparators(archivePath)} + tops);
|
||||
return tar.waitForFinished(30000) && tar.exitStatus() == QProcess::NormalExit
|
||||
&& tar.exitCode() == 0;
|
||||
}
|
||||
|
||||
QString Fixtures::sha1(const QByteArray &data)
|
||||
{
|
||||
return QString::fromLatin1(QCryptographicHash::hash(data, QCryptographicHash::Sha1).toHex());
|
||||
}
|
||||
|
||||
QString Fixtures::sha256(const QByteArray &data)
|
||||
{
|
||||
return QString::fromLatin1(QCryptographicHash::hash(data, QCryptographicHash::Sha256).toHex());
|
||||
}
|
||||
|
||||
QStringList Fixtures::listTree(const QString &dir)
|
||||
{
|
||||
QStringList result;
|
||||
QDirIterator it(dir, QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot,
|
||||
QDirIterator::Subdirectories);
|
||||
const QDir base(dir);
|
||||
while (it.hasNext())
|
||||
result << base.relativeFilePath(it.next());
|
||||
result.sort();
|
||||
return result;
|
||||
}
|
||||
|
||||
QString Fixtures::javaExecutableName()
|
||||
{
|
||||
#if defined(Q_OS_WIN)
|
||||
return QStringLiteral("java.exe");
|
||||
#else
|
||||
return QStringLiteral("java");
|
||||
#endif
|
||||
}
|
||||
|
||||
void Fixtures::configureFakeJava(const QString &javaPath, const QString &version,
|
||||
const QStringList &config)
|
||||
{
|
||||
QStringList lines{QStringLiteral("version=") + version};
|
||||
lines += config;
|
||||
write(QFileInfo(javaPath).absolutePath() + QStringLiteral("/fake-java.cfg"),
|
||||
lines.join(u'\n').toUtf8() + '\n');
|
||||
}
|
||||
|
||||
QString Fixtures::installFakeJava(const QString &dir, const QString &version,
|
||||
const QStringList &config)
|
||||
{
|
||||
const QString binDir = dir + QStringLiteral("/bin");
|
||||
QDir().mkpath(binDir);
|
||||
const QString java = binDir + u'/' + javaExecutableName();
|
||||
QFile::remove(java);
|
||||
if (!QFile::copy(QStringLiteral(BILAUNCHER_FAKE_JAVA), java))
|
||||
qFatal("Не удалось скопировать fake_java в %s", qPrintable(java));
|
||||
QFile::setPermissions(java, QFile::permissions(java) | QFileDevice::ExeOwner
|
||||
| QFileDevice::ExeGroup | QFileDevice::ExeOther);
|
||||
#if defined(Q_OS_WIN)
|
||||
const QString javaw = binDir + QStringLiteral("/javaw.exe");
|
||||
QFile::remove(javaw);
|
||||
QFile::copy(java, javaw);
|
||||
#endif
|
||||
configureFakeJava(java, version, config);
|
||||
return java;
|
||||
}
|
||||
Reference in new issue
Block a user