diff --git a/generateFabric.py b/generateFabric.py index 2f897a5..333145c 100755 --- a/generateFabric.py +++ b/generateFabric.py @@ -1,5 +1,6 @@ from meta.fabricutil import * -from meta.common import ensure_component_dir, polymc_path, upstream_path +from meta.common import ensure_component_dir, polymc_path, upstream_path, transform_maven_key +from meta.common.fabric import JARS_DIR, INSTALLER_INFO_DIR, META_DIR, INTERMEDIARY_COMPONENT, LOADER_COMPONENT PMC_DIR = polymc_path() UPSTREAM_DIR = upstream_path() @@ -7,91 +8,101 @@ UPSTREAM_DIR = upstream_path() ensure_component_dir("net.fabricmc.fabric-loader") ensure_component_dir("net.fabricmc.intermediary") -# turn loader versions into packages -loaderRecommended = [] -loaderVersions = [] -intermediaryRecommended = [] -intermediaryVersions = [] - -def loadJarInfo(mavenKey): - with open(UPSTREAM_DIR + "/fabric/jars/" + mavenKey.replace(":", ".") + ".json", 'r', +def load_jar_info(artifact_key): + with open(os.path.join(UPSTREAM_DIR, JARS_DIR, f"{artifact_key}.json"), 'r', encoding='utf-8') as jarInfoFile: return FabricJarInfo(json.load(jarInfoFile)) -def processLoaderVersion(loaderVersion, it, loaderData): - verStable = it["stable"] - if (len(loaderRecommended) < 1) and verStable: - loaderRecommended.append(loaderVersion) - versionJarInfo = loadJarInfo(it["maven"]) - version = PolyMCVersionFile(name="Fabric Loader", uid="net.fabricmc.fabric-loader", version=loaderVersion) - version.releaseTime = versionJarInfo.releaseTime - version.requires = [DependencyEntry(uid='net.fabricmc.intermediary')] - version.order = 10 - version.type = "release" - if isinstance(loaderData.mainClass, dict): - version.mainClass = loaderData.mainClass["client"] +def load_installer_info(version): + with open(os.path.join(UPSTREAM_DIR, INSTALLER_INFO_DIR, f"{version}.json"), 'r', + encoding='utf-8') as loaderVersionFile: + data = json.load(loaderVersionFile) + return FabricInstallerDataV1(data) + + +def process_loader_version(entry) -> PolyMCVersionFile: + jar_info = load_jar_info(transform_maven_key(entry["maven"])) + installer_info = load_installer_info(entry["version"]) + + v = PolyMCVersionFile(name="Fabric Loader", uid="net.fabricmc.fabric-loader", version=entry["version"]) + v.releaseTime = jar_info.releaseTime + v.requires = [DependencyEntry(uid='net.fabricmc.intermediary')] + v.order = 10 + v.type = "release" + if isinstance(installer_info.mainClass, dict): + v.mainClass = installer_info.mainClass["client"] else: - version.mainClass = loaderData.mainClass - version.libraries = [] - version.libraries.extend(loaderData.libraries.common) - version.libraries.extend(loaderData.libraries.client) - loaderLib = PolyMCLibrary(name=GradleSpecifier(it["maven"]), url="https://maven.fabricmc.net") - version.libraries.append(loaderLib) - loaderVersions.append(version) + v.mainClass = installer_info.mainClass + v.libraries = [] + v.libraries.extend(installer_info.libraries.common) + v.libraries.extend(installer_info.libraries.client) + loader_lib = PolyMCLibrary(name=GradleSpecifier(entry["maven"]), url="https://maven.fabricmc.net") + v.libraries.append(loader_lib) + return v -def processIntermediaryVersion(it): - intermediaryRecommended.append(it["version"]) - versionJarInfo = loadJarInfo(it["maven"]) - version = PolyMCVersionFile(name="Intermediary Mappings", uid="net.fabricmc.intermediary", version=it["version"]) - version.releaseTime = versionJarInfo.releaseTime - version.requires = [DependencyEntry(uid='net.minecraft', equals=it["version"])] - version.order = 11 - version.type = "release" - version.libraries = [] - version.volatile = True - mappingLib = PolyMCLibrary(name=GradleSpecifier(it["maven"]), url="https://maven.fabricmc.net") - version.libraries.append(mappingLib) - intermediaryVersions.append(version) +def process_intermediary_version(entry) -> PolyMCVersionFile: + jar_info = load_jar_info(transform_maven_key(entry["maven"])) + + v = PolyMCVersionFile(name="Intermediary Mappings", uid="net.fabricmc.intermediary", version=entry["version"]) + v.releaseTime = jar_info.releaseTime + v.requires = [DependencyEntry(uid='net.minecraft', equals=entry["version"])] + v.order = 11 + v.type = "release" + v.libraries = [] + v.volatile = True + intermediary_lib = PolyMCLibrary(name=GradleSpecifier(entry["maven"]), url="https://maven.fabricmc.net") + v.libraries.append(intermediary_lib) + return v -with open(UPSTREAM_DIR + "/fabric/meta-v2/loader.json", 'r', encoding='utf-8') as loaderVersionIndexFile: - loaderVersionIndex = json.load(loaderVersionIndexFile) - for it in loaderVersionIndex: - version = it["version"] - with open(UPSTREAM_DIR + "/fabric/loader-installer-json/" + version + ".json", 'r', - encoding='utf-8') as loaderVersionFile: - ldata = json.load(loaderVersionFile) - ldata = FabricInstallerDataV1(ldata) - processLoaderVersion(version, it, ldata) +def main(): + recommended_loader_versions = [] + recommended_intermediary_versions = [] -with open(UPSTREAM_DIR + "/fabric/meta-v2/intermediary.json", 'r', encoding='utf-8') as intermediaryVersionIndexFile: - intermediaryVersionIndex = json.load(intermediaryVersionIndexFile) - for it in intermediaryVersionIndex: - processIntermediaryVersion(it) + 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}") -for version in loaderVersions: - outFilepath = PMC_DIR + "/net.fabricmc.fabric-loader/%s.json" % version.version - with open(outFilepath, 'w') as outfile: - json.dump(version.to_json(), outfile, sort_keys=True, indent=4) + v = process_loader_version(entry) -sharedData = PolyMCSharedPackageData(uid='net.fabricmc.fabric-loader', name='Fabric Loader') -sharedData.recommended = loaderRecommended -sharedData.description = "Fabric Loader is a tool to load Fabric-compatible mods in game environments." -sharedData.projectUrl = "https://fabricmc.net" -sharedData.authors = ["Fabric Developers"] -sharedData.write() + if not recommended_loader_versions: # first (newest) loader is recommended + recommended_loader_versions.append(version) -for version in intermediaryVersions: - outFilepath = PMC_DIR + "/net.fabricmc.intermediary/%s.json" % version.version - with open(outFilepath, 'w') as outfile: - json.dump(version.to_json(), outfile, sort_keys=True, indent=4) + with open(os.path.join(PMC_DIR, LOADER_COMPONENT, f"{v.version}.json"), 'w') as outfile: + json.dump(v.to_json(), outfile, sort_keys=True, indent=4) -sharedData = PolyMCSharedPackageData(uid='net.fabricmc.intermediary', name='Intermediary Mappings') -sharedData.recommended = intermediaryRecommended -sharedData.description = "Intermediary mappings allow using Fabric Loader with mods for Minecraft in a more compatible manner." -sharedData.projectUrl = "https://fabricmc.net" -sharedData.authors = ["Fabric Developers"] -sharedData.write() + with open(os.path.join(UPSTREAM_DIR, META_DIR, "intermediary.json"), 'r', encoding='utf-8') as f: + intermediary_version_index = json.load(f) + for entry in intermediary_version_index: + version = entry["version"] + print(f"Processing intermediary {version}") + + v = process_intermediary_version(entry) + + recommended_intermediary_versions.append(version) # all intermediaries are recommended + + with open(os.path.join(PMC_DIR, INTERMEDIARY_COMPONENT, f"{v.version}.json"), 'w') as outfile: + json.dump(v.to_json(), outfile, sort_keys=True, indent=4) + + package = PolyMCSharedPackageData(uid=LOADER_COMPONENT, name='Fabric Loader') + package.recommended = recommended_loader_versions + package.description = "Fabric Loader is a tool to load Fabric-compatible mods in game environments." + package.projectUrl = "https://fabricmc.net" + package.authors = ["Fabric Developers"] + package.write() + + package = PolyMCSharedPackageData(uid=INTERMEDIARY_COMPONENT, name='Intermediary Mappings') + package.recommended = recommended_intermediary_versions + package.description = "Intermediary mappings allow using Fabric Loader with mods for Minecraft in a more compatible manner." + package.projectUrl = "https://fabricmc.net" + package.authors = ["Fabric Developers"] + package.write() + + +if __name__ == '__main__': + main() diff --git a/meta/common.py b/meta/common/__init__.py similarity index 59% rename from meta/common.py rename to meta/common/__init__.py index 5454f51..77aa996 100644 --- a/meta/common.py +++ b/meta/common/__init__.py @@ -1,5 +1,7 @@ import os +DATETIME_FORMAT_HTTP = "%a, %d %b %Y %H:%M:%S %Z" + def polymc_path(): if "PMC_DIR" in os.environ: @@ -13,7 +15,17 @@ def upstream_path(): return "upstream" +def ensure_upstream_dir(path): + path = os.path.join(upstream_path(), path) + if not os.path.exists(path): + os.makedirs(path) + + def ensure_component_dir(component_id): path = os.path.join(polymc_path(), component_id) if not os.path.exists(path): os.makedirs(path) + + +def transform_maven_key(maven_key: str): + return maven_key.replace(":", ".") diff --git a/meta/common/fabric.py b/meta/common/fabric.py new file mode 100644 index 0000000..0861730 --- /dev/null +++ b/meta/common/fabric.py @@ -0,0 +1,10 @@ +from os.path import join + +BASE_DIR = "fabric" + +JARS_DIR = join(BASE_DIR, "jars") +INSTALLER_INFO_DIR = join(BASE_DIR, "loader-installer-json") +META_DIR = join(BASE_DIR, "loader-installer-json") + +LOADER_COMPONENT = "net.fabricmc.fabric-loader" +INTERMEDIARY_COMPONENT = "net.fabricmc.intermediary" diff --git a/meta/metautil.py b/meta/metautil.py index e417bd6..11c4009 100644 --- a/meta/metautil.py +++ b/meta/metautil.py @@ -4,8 +4,9 @@ import os import iso8601 from .jsonobject import * +from .common import polymc_path -PMC_DIR = os.environ["PMC_DIR"] +PMC_DIR = polymc_path() class ISOTimestampProperty(AbstractDateProperty): diff --git a/updateFabric.py b/updateFabric.py index 57e6bee..f48858d 100755 --- a/updateFabric.py +++ b/updateFabric.py @@ -5,33 +5,32 @@ import requests from cachecontrol import CacheControl from cachecontrol.caches import FileCache from meta.fabricutil import * +from meta.common import DATETIME_FORMAT_HTTP, upstream_path, ensure_upstream_dir, transform_maven_key +from meta.common.fabric import JARS_DIR, INSTALLER_INFO_DIR, META_DIR -DATETIME_FORMAT_HTTP = "%a, %d %b %Y %H:%M:%S %Z" +UPSTREAM_DIR = upstream_path() -UPSTREAM_DIR = os.environ["UPSTREAM_DIR"] +ensure_upstream_dir(JARS_DIR) +ensure_upstream_dir(INSTALLER_INFO_DIR) +ensure_upstream_dir(META_DIR) forever_cache = FileCache('caches/http_cache', forever=True) sess = CacheControl(requests.Session(), forever_cache) -def mkdirs(path): - if not os.path.exists(path): - os.makedirs(path) - - def filehash(filename, hashtype, blocksize=65536): - hash = hashtype() + h = hashtype() with open(filename, "rb") as f: for block in iter(lambda: f.read(blocksize), b""): - hash.update(block) - return hash.hexdigest() + h.update(block) + return h.hexdigest() -def get_maven_url(mavenKey, server, ext): - mavenParts = mavenKey.split(":", 3) - mavenVerUrl = server + mavenParts[0].replace(".", "/") + "/" + mavenParts[1] + "/" + mavenParts[2] + "/" - mavenUrl = mavenVerUrl + mavenParts[1] + "-" + mavenParts[2] + ext - return mavenUrl +def get_maven_url(maven_key, server, ext): + parts = maven_key.split(":", 3) + maven_ver_url = server + parts[0].replace(".", "/") + "/" + parts[1] + "/" + parts[2] + "/" + maven_url = maven_ver_url + parts[1] + "-" + parts[2] + ext + return maven_url def get_json_file(path, url): @@ -56,12 +55,11 @@ def head_file(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.raise_for_status() - with open(path, 'wb') as f: - for chunk in r.iter_content(chunk_size=128): - f.write(chunk) + for chunk in r.iter_content(chunk_size=128): + f.write(chunk) def compute_jar_file(path, url): @@ -101,21 +99,24 @@ def compute_jar_file(path, url): json.dump(data.to_json(), outfile, sort_keys=True, indent=4) -mkdirs(UPSTREAM_DIR + "/fabric/meta-v2") -mkdirs(UPSTREAM_DIR + "/fabric/loader-installer-json") -mkdirs(UPSTREAM_DIR + "/fabric/jars") +def main(): + # get the version list for each component we are interested in + for component in ["intermediary", "loader"]: + index = get_json_file(os.path.join(UPSTREAM_DIR, META_DIR, f"{component}.json"), + "https://meta.fabricmc.net/v2/versions/" + component) + for it in index: + print(f"Processing {component} {it['version']} ") + jar_maven_url = get_maven_url(it["maven"], "https://maven.fabricmc.net/", ".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 component in ["intermediary", "loader"]: - index = get_json_file(UPSTREAM_DIR + "/fabric/meta-v2/" + component + ".json", - "https://meta.fabricmc.net/v2/versions/" + component) - for it in index: - jarMavenUrl = get_maven_url(it["maven"], "https://maven.fabricmc.net/", ".jar") - compute_jar_file(UPSTREAM_DIR + "/fabric/jars/" + it["maven"].replace(":", "."), jarMavenUrl) + # for each loader, download installer JSON file from maven + with open(os.path.join(UPSTREAM_DIR, META_DIR, "loader.json"), 'r', encoding='utf-8') as loaderVersionIndexFile: + loader_version_index = json.load(loaderVersionIndexFile) + for it in loader_version_index: + print(f"Downloading installer info for loader {it['version']} ") + maven_url = get_maven_url(it["maven"], "https://maven.fabricmc.net/", ".json") + 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 + "/fabric/meta-v2/loader.json", 'r', encoding='utf-8') as loaderVersionIndexFile: - loaderVersionIndex = json.load(loaderVersionIndexFile) - for it in loaderVersionIndex: - mavenUrl = get_maven_url(it["maven"], "https://maven.fabricmc.net/", ".json") - get_json_file(UPSTREAM_DIR + "/fabric/loader-installer-json/" + it["version"] + ".json", mavenUrl) + +if __name__ == '__main__': + main()