refactor: switch quilt to pydantic models

This commit is contained in:
Sefa Eyeoglu 2022-04-07 18:49:43 +02:00
parent be1c744852
commit 4d351a2937
No known key found for this signature in database
GPG Key ID: C10411294912A422
3 changed files with 162 additions and 144 deletions

View File

@ -1,111 +1,111 @@
from fabricutil import * import json
import os
PMC_DIR = os.environ["PMC_DIR"] from meta.common import ensure_component_dir, polymc_path, upstream_path, transform_maven_key
UPSTREAM_DIR = os.environ["UPSTREAM_DIR"] from meta.common.quilt import JARS_DIR, INSTALLER_INFO_DIR, META_DIR, INTERMEDIARY_COMPONENT, LOADER_COMPONENT, \
USE_QUILT_MAPPINGS
from meta.model import MetaVersion, Dependency, Library, MetaPackage, GradleSpecifier
from meta.model.fabric import FabricJarInfo, FabricInstallerDataV1, FabricMainClasses
# TODO: Switch to Quilt Mappings once the time has come PMC_DIR = polymc_path()
USE_QUILT_MAPPINGS = False UPSTREAM_DIR = upstream_path()
# turn loader versions into packages ensure_component_dir(LOADER_COMPONENT)
loaderRecommended = [] ensure_component_dir(INTERMEDIARY_COMPONENT)
loaderVersions = []
intermediaryRecommended = []
intermediaryVersions = []
def mkdirs(path): def load_jar_info(artifact_key) -> FabricJarInfo:
if not os.path.exists(path): return FabricJarInfo.parse_file(os.path.join(UPSTREAM_DIR, JARS_DIR, f"{artifact_key}.json"))
os.makedirs(path)
mkdirs(PMC_DIR + "/org.quiltmc.quilt-loader") def load_installer_info(version) -> FabricInstallerDataV1:
mkdirs(PMC_DIR + "/org.quiltmc.quilt-mappings") return FabricInstallerDataV1.parse_file(os.path.join(UPSTREAM_DIR, INSTALLER_INFO_DIR, f"{version}.json"))
def loadJarInfo(mavenKey): def process_loader_version(entry) -> MetaVersion:
with open(UPSTREAM_DIR + "/quilt/jars/" + mavenKey.replace(":", ".") + ".json", 'r', jar_info = load_jar_info(transform_maven_key(entry["maven"]))
encoding='utf-8') as jarInfoFile: installer_info = load_installer_info(entry["version"])
return FabricJarInfo(json.load(jarInfoFile))
v = MetaVersion(name="Quilt Loader", uid=LOADER_COMPONENT, version=entry["version"])
v.release_time = jar_info.release_time
v.requires = [Dependency(uid=INTERMEDIARY_COMPONENT)]
v.order = 10
v.type = "release"
if isinstance(installer_info.main_class, FabricMainClasses):
v.main_class = installer_info.main_class.client
else:
v.main_class = installer_info.main_class
v.libraries = []
v.libraries.extend(installer_info.libraries.common)
v.libraries.extend(installer_info.libraries.client)
loader_lib = Library(name=GradleSpecifier.from_string(entry["maven"]),
url="https://maven.quiltmc.org/repository/release")
v.libraries.append(loader_lib)
return v
def processLoaderVersion(loaderVersion, it, loaderData): def process_intermediary_version(entry) -> MetaVersion:
if (len(loaderRecommended) < 1): # TODO figure out actual stable version minecraft_version = entry["version"].split("+", 2)[0] # version format is like 1.18.2-pre1+build.1
loaderRecommended.append(loaderVersion)
versionJarInfo = loadJarInfo(it["maven"]) jar_info = load_jar_info(transform_maven_key(entry["maven"]))
version = PolyMCVersionFile(name="Quilt Loader", uid="org.quiltmc.quilt-loader", version=loaderVersion)
version.releaseTime = versionJarInfo.releaseTime v = MetaVersion(name="Quilt Intermediary Mappings", uid=INTERMEDIARY_COMPONENT, version=entry["version"])
v.release_time = jar_info.release_time
v.requires = [Dependency(uid='net.minecraft', equals=minecraft_version)]
v.order = 11
v.type = "release"
v.libraries = []
v.volatile = True
intermediary_lib = Library(name=GradleSpecifier.from_string(entry["maven"]),
url="https://maven.quiltmc.org/repository/release")
v.libraries.append(intermediary_lib)
return v
def main():
recommended_loader_versions = []
recommended_intermediary_versions = []
with open(os.path.join(UPSTREAM_DIR, META_DIR, "loader.json"), 'r', encoding='utf-8') as f:
loader_version_index = json.load(f)
for entry in loader_version_index:
version = entry["version"]
print(f"Processing loader {version}")
v = process_loader_version(entry)
if not recommended_loader_versions: # first (newest) loader is recommended
recommended_loader_versions.append(version)
v.write(os.path.join(PMC_DIR, LOADER_COMPONENT, f"{v.version}.json"))
if USE_QUILT_MAPPINGS: if USE_QUILT_MAPPINGS:
version.requires = [DependencyEntry(uid='org.quiltmc.quilt-mappings')] with open(os.path.join(UPSTREAM_DIR, META_DIR, "quilt-mappings.json"), 'r', encoding='utf-8') as f:
else: intermediary_version_index = json.load(f)
version.requires = [DependencyEntry(uid='net.fabricmc.intermediary')] for entry in intermediary_version_index:
version.order = 10 version = entry["version"]
version.type = "release" print(f"Processing intermediary {version}")
if isinstance(loaderData.mainClass, dict):
version.mainClass = loaderData.mainClass["client"] v = process_intermediary_version(entry)
else:
version.mainClass = loaderData.mainClass recommended_intermediary_versions.append(version) # all intermediaries are recommended
version.libraries = []
version.libraries.extend(loaderData.libraries.common) v.write(os.path.join(PMC_DIR, INTERMEDIARY_COMPONENT, f"{v.version}.json"))
version.libraries.extend(loaderData.libraries.client)
loaderLib = PolyMCLibrary(name=GradleSpecifier(it["maven"]), url="https://maven.quiltmc.org/repository/release") package = MetaPackage(uid=LOADER_COMPONENT, name='Quilt Loader')
version.libraries.append(loaderLib) package.recommended = recommended_loader_versions
loaderVersions.append(version) package.description = "The Quilt project is an open, community-driven modding toolchain designed primarily for Minecraft."
package.project_url = "https://quiltmc.org/"
package.authors = ["Quilt Project"]
package.write(os.path.join(PMC_DIR, LOADER_COMPONENT, "package.json"))
package = MetaPackage(uid=INTERMEDIARY_COMPONENT, name='Quilt Intermediary Mappings')
package.recommended = recommended_intermediary_versions
package.description = "Intermediary mappings allow using Quilt Loader with mods for Minecraft in a more compatible manner."
package.project_url = "https://quiltmc.org/"
package.authors = ["Quilt Project"]
package.write(os.path.join(PMC_DIR, INTERMEDIARY_COMPONENT, "package.json"))
def processIntermediaryVersion(it): if __name__ == '__main__':
minecraftVersion = it["version"].split("+", 2)[0] # version format is like 1.18.2-pre1+build.1 main()
intermediaryRecommended.append(it["version"])
versionJarInfo = loadJarInfo(it["maven"])
version = PolyMCVersionFile(name="Quilt Intermediary Mappings", uid="org.quiltmc.quilt-mappings", version=it["version"])
version.releaseTime = versionJarInfo.releaseTime
version.requires = [DependencyEntry(uid='net.minecraft', equals=minecraftVersion)]
version.order = 11
version.type = "release"
version.libraries = []
version.volatile = True
mappingLib = PolyMCLibrary(name=GradleSpecifier(it["maven"]), url="https://maven.quiltmc.org/repository/release")
version.libraries.append(mappingLib)
intermediaryVersions.append(version)
with open(UPSTREAM_DIR + "/quilt/meta-v3/loader.json", 'r', encoding='utf-8') as loaderVersionIndexFile:
loaderVersionIndex = json.load(loaderVersionIndexFile)
for it in loaderVersionIndex:
version = it["version"]
with open(UPSTREAM_DIR + "/quilt/loader-installer-json/" + version + ".json", 'r',
encoding='utf-8') as loaderVersionFile:
ldata = json.load(loaderVersionFile)
ldata = FabricInstallerDataV1(ldata)
processLoaderVersion(version, it, ldata)
if USE_QUILT_MAPPINGS:
with open(UPSTREAM_DIR + "/quilt/meta-v3/quilt-mappings.json", 'r', encoding='utf-8') as intermediaryVersionIndexFile:
intermediaryVersionIndex = json.load(intermediaryVersionIndexFile)
for it in intermediaryVersionIndex:
processIntermediaryVersion(it)
for version in loaderVersions:
outFilepath = PMC_DIR + "/org.quiltmc.quilt-loader/%s.json" % version.version
with open(outFilepath, 'w') as outfile:
json.dump(version.to_json(), outfile, sort_keys=True, indent=4)
sharedData = PolyMCSharedPackageData(uid='org.quiltmc.quilt-loader', name='Quilt Loader')
sharedData.recommended = loaderRecommended
sharedData.description = "The Quilt project is an open, community-driven modding toolchain designed primarily for Minecraft."
sharedData.projectUrl = "https://quiltmc.org"
sharedData.authors = ["Quilt Project"]
sharedData.write()
if USE_QUILT_MAPPINGS:
for version in intermediaryVersions:
outFilepath = PMC_DIR + "/org.quiltmc.quilt-mappings/%s.json" % version.version
with open(outFilepath, 'w') as outfile:
json.dump(version.to_json(), outfile, sort_keys=True, indent=4)
sharedData = PolyMCSharedPackageData(uid='org.quiltmc.quilt-mappings', name='Quilt Intermediary Mappings')
sharedData.recommended = intermediaryRecommended
sharedData.description = "Intermediary mappings allow using Quilt Loader with mods for Minecraft in a more compatible manner."
sharedData.projectUrl = "https://quiltmc.org"
sharedData.authors = ["Quilt Project"]
sharedData.write()

17
meta/common/quilt.py Normal file
View File

@ -0,0 +1,17 @@
from os.path import join
from .fabric import INTERMEDIARY_COMPONENT as FABRIC_INTERMEDIARY_COMPONENT
# Right now Quilt recommends using Fabric's intermediary
USE_QUILT_MAPPINGS = False
BASE_DIR = "quilt"
JARS_DIR = join(BASE_DIR, "jars")
INSTALLER_INFO_DIR = join(BASE_DIR, "loader-installer-json")
META_DIR = join(BASE_DIR, "meta-v3")
LOADER_COMPONENT = "org.quiltmc.quilt-loader"
INTERMEDIARY_COMPONENT = "org.quiltmc.quilt-mappings"
if not USE_QUILT_MAPPINGS:
INTERMEDIARY_COMPONENT = FABRIC_INTERMEDIARY_COMPONENT

View File

@ -1,37 +1,41 @@
import hashlib import hashlib
import json
import os
import zipfile import zipfile
from datetime import datetime
import requests import requests
from cachecontrol import CacheControl from cachecontrol import CacheControl
from cachecontrol.caches import FileCache from cachecontrol.caches import FileCache
from fabricutil import *
DATETIME_FORMAT_HTTP = "%a, %d %b %Y %H:%M:%S %Z" from meta.common import upstream_path, ensure_upstream_dir, transform_maven_key
from meta.common.quilt import JARS_DIR, INSTALLER_INFO_DIR, META_DIR
from meta.common.fabric import DATETIME_FORMAT_HTTP
from meta.model.fabric import FabricJarInfo
UPSTREAM_DIR = os.environ["UPSTREAM_DIR"] UPSTREAM_DIR = upstream_path()
ensure_upstream_dir(JARS_DIR)
ensure_upstream_dir(INSTALLER_INFO_DIR)
ensure_upstream_dir(META_DIR)
forever_cache = FileCache('caches/http_cache', forever=True) forever_cache = FileCache('caches/http_cache', forever=True)
sess = CacheControl(requests.Session(), forever_cache) sess = CacheControl(requests.Session(), forever_cache)
def mkdirs(path):
if not os.path.exists(path):
os.makedirs(path)
def filehash(filename, hashtype, blocksize=65536): def filehash(filename, hashtype, blocksize=65536):
hash = hashtype() h = hashtype()
with open(filename, "rb") as f: with open(filename, "rb") as f:
for block in iter(lambda: f.read(blocksize), b""): for block in iter(lambda: f.read(blocksize), b""):
hash.update(block) h.update(block)
return hash.hexdigest() return h.hexdigest()
def get_maven_url(mavenKey, server, ext): def get_maven_url(maven_key, server, ext):
mavenParts = mavenKey.split(":", 3) parts = maven_key.split(":", 3)
mavenVerUrl = server + mavenParts[0].replace(".", "/") + "/" + mavenParts[1] + "/" + mavenParts[2] + "/" maven_ver_url = server + parts[0].replace(".", "/") + "/" + parts[1] + "/" + parts[2] + "/"
mavenUrl = mavenVerUrl + mavenParts[1] + "-" + mavenParts[2] + ext maven_url = maven_ver_url + parts[1] + "-" + parts[2] + ext
return mavenUrl return maven_url
def get_json_file(path, url): def get_json_file(path, url):
@ -56,12 +60,11 @@ def head_file(url):
def get_binary_file(path, url): def get_binary_file(path, url):
with open(path, 'w', encoding='utf-8') as f: with open(path, 'wb') as f:
r = sess.get(url) r = sess.get(url)
r.raise_for_status() r.raise_for_status()
with open(path, 'wb') as f: for chunk in r.iter_content(chunk_size=128):
for chunk in r.iter_content(chunk_size=128): f.write(chunk)
f.write(chunk)
def compute_jar_file(path, url): def compute_jar_file(path, url):
@ -70,7 +73,7 @@ def compute_jar_file(path, url):
try: try:
# Let's not download a Jar file if we don't need to. # Let's not download a Jar file if we don't need to.
headers = head_file(url) headers = head_file(url)
tstamp = datetime.datetime.strptime(headers["Last-Modified"], DATETIME_FORMAT_HTTP) tstamp = datetime.strptime(headers["Last-Modified"], DATETIME_FORMAT_HTTP)
sha1 = get_plaintext(url + ".sha1") sha1 = get_plaintext(url + ".sha1")
sha256 = get_plaintext(url + ".sha256") sha256 = get_plaintext(url + ".sha256")
size = int(headers["Content-Length"]) size = int(headers["Content-Length"])
@ -80,11 +83,11 @@ def compute_jar_file(path, url):
jar_path = path + ".jar" jar_path = path + ".jar"
get_binary_file(jar_path, url) get_binary_file(jar_path, url)
tstamp = datetime.datetime.fromtimestamp(0) tstamp = datetime.fromtimestamp(0)
with zipfile.ZipFile(jar_path, 'r') as jar: with zipfile.ZipFile(jar_path) as jar:
allinfo = jar.infolist() allinfo = jar.infolist()
for info in allinfo: for info in allinfo:
tstamp_new = datetime.datetime(*info.date_time) tstamp_new = datetime(*info.date_time)
if tstamp_new > tstamp: if tstamp_new > tstamp:
tstamp = tstamp_new tstamp = tstamp_new
@ -92,30 +95,28 @@ def compute_jar_file(path, url):
sha256 = filehash(jar_path, hashlib.sha256) sha256 = filehash(jar_path, hashlib.sha256)
size = os.path.getsize(jar_path) size = os.path.getsize(jar_path)
data = FabricJarInfo() data = FabricJarInfo(release_time=tstamp, sha1=sha1, sha256=sha256, size=size)
data.releaseTime = tstamp data.write(path + ".json")
data.sha1 = sha1
data.sha256 = sha256
data.size = size
with open(path + ".json", 'w') as outfile:
json.dump(data.to_json(), outfile, sort_keys=True, indent=4)
mkdirs(UPSTREAM_DIR + "/quilt/meta-v3") def main():
mkdirs(UPSTREAM_DIR + "/quilt/loader-installer-json") # get the version list for each component we are interested in
mkdirs(UPSTREAM_DIR + "/quilt/jars") for component in ["quilt-mappings", "loader"]:
index = get_json_file(os.path.join(UPSTREAM_DIR, META_DIR, f"{component}.json"),
"https://meta.quiltmc.org/v3/versions/" + component)
for it in index:
print(f"Processing {component} {it['version']} ")
jar_maven_url = get_maven_url(it["maven"], "https://maven.quiltmc.org/repository/release/", ".jar")
compute_jar_file(os.path.join(UPSTREAM_DIR, JARS_DIR, transform_maven_key(it["maven"])), jar_maven_url)
# get the version list for each component we are interested in # for each loader, download installer JSON file from maven
for component in ["quilt-mappings", "loader"]: with open(os.path.join(UPSTREAM_DIR, META_DIR, "loader.json"), 'r', encoding='utf-8') as loaderVersionIndexFile:
index = get_json_file(UPSTREAM_DIR + "/quilt/meta-v3/" + component + ".json", loader_version_index = json.load(loaderVersionIndexFile)
"https://meta.quiltmc.org/v3/versions/" + component) for it in loader_version_index:
for it in index: print(f"Downloading installer info for loader {it['version']} ")
jarMavenUrl = get_maven_url(it["maven"], "https://maven.quiltmc.org/repository/release/", ".jar") maven_url = get_maven_url(it["maven"], "https://maven.quiltmc.org/repository/release/", ".json")
compute_jar_file(UPSTREAM_DIR + "/quilt/jars/" + it["maven"].replace(":", "."), jarMavenUrl) get_json_file(os.path.join(UPSTREAM_DIR, INSTALLER_INFO_DIR, f"{it['version']}.json"), maven_url)
# for each loader, download installer JSON file from maven
with open(UPSTREAM_DIR + "/quilt/meta-v3/loader.json", 'r', encoding='utf-8') as loaderVersionIndexFile: if __name__ == '__main__':
loaderVersionIndex = json.load(loaderVersionIndexFile) main()
for it in loaderVersionIndex:
mavenUrl = get_maven_url(it["maven"], "https://maven.quiltmc.org/repository/release/", ".json")
get_json_file(UPSTREAM_DIR + "/quilt/loader-installer-json/" + it["version"] + ".json", mavenUrl)