diff --git a/generateLiteloader.py b/generateLiteloader.py index 63ffc2e..1af84a2 100755 --- a/generateLiteloader.py +++ b/generateLiteloader.py @@ -1,93 +1,108 @@ -from meta.liteloaderutil import * +import os +from datetime import datetime +from typing import List, Tuple, Dict, Optional + from meta.common import ensure_component_dir, polymc_path, upstream_path +from meta.common.liteloader import LITELOADER_COMPONENT, VERSIONS_FILE +from meta.common.mojang import MINECRAFT_COMPONENT +from meta.model import MetaVersion, GradleSpecifier, Library, MetaPackage, Dependency +from meta.model.liteloader import LiteloaderIndex, LiteloaderArtefact PMC_DIR = polymc_path() UPSTREAM_DIR = upstream_path() -ensure_component_dir("com.mumfrey.liteloader") +ensure_component_dir(LITELOADER_COMPONENT) -# load the locally cached version list -def loadLiteloaderJson(): - with open(UPSTREAM_DIR + "/liteloader/versions.json", 'r', encoding='utf-8') as f: - return LiteloaderIndex(json.load(f)) - - -remoteVersionlist = loadLiteloaderJson() - - -def processArtefacts(mcVersion, liteloader, notSnapshots): - versions = [] - lookup = {} - latestVersion = None +def process_artefacts(mc_version: str, artefacts: Dict[str, LiteloaderArtefact], is_snapshot: bool) \ + -> Tuple[List[MetaVersion], Optional[MetaVersion]]: + versions: List[MetaVersion] = [] + lookup: Dict[str, MetaVersion] = {} + latest_version = None latest = None - for id, artefact in liteloader.items(): - if id == 'latest': - latestVersion = artefact.version + for x, artefact in artefacts.items(): + if x == 'latest': + latest_version = artefact.version continue - version = PolyMCVersionFile(name="LiteLoader", uid="com.mumfrey.liteloader", version=artefact.version) - version.requires = [DependencyEntry(uid='net.minecraft', equals=mcVersion)] - version.releaseTime = datetime.datetime.utcfromtimestamp(int(artefact.timestamp)) - version.addTweakers = [artefact.tweakClass] - version.mainClass = "net.minecraft.launchwrapper.Launch" - version.order = 10 - if notSnapshots: - version.type = "release" - else: - version.type = "snapshot" - lookup[version.version] = version - libraries = artefact.libraries + v = MetaVersion( + name="LiteLoader", + uid=LITELOADER_COMPONENT, + version=artefact.version, + requires=[Dependency(uid=MINECRAFT_COMPONENT, equals=mc_version)], + release_time=datetime.utcfromtimestamp(int(artefact.timestamp)), + additional_tweakers=[artefact.tweakClass], + main_class="net.minecraft.launchwrapper.Launch", + order=10, + libraries=artefact.libraries, + type="release") + + if is_snapshot: + v.type = "snapshot" + # hack to make broken liteloader versions work - for lib in libraries: + for lib in v.libraries: if lib.name == GradleSpecifier("org.ow2.asm:asm-all:5.0.3"): lib.url = "https://repo.maven.apache.org/maven2/" if lib.name == GradleSpecifier("org.ow2.asm:asm-all:5.2"): lib.url = "http://repo.liteloader.com/" - liteloaderLib = PolyMCLibrary( - name=GradleSpecifier("com.mumfrey:liteloader:%s" % version.version), + + liteloader_lib = Library( + name=GradleSpecifier("com.mumfrey:liteloader:%s" % v.version), url="http://dl.liteloader.com/versions/" ) - if not notSnapshots: - liteloaderLib.mmcHint = "always-stale" - libraries.append(liteloaderLib) - version.libraries = libraries - versions.append(version) - if latestVersion: - latest = lookup[latestVersion] + if is_snapshot: + liteloader_lib.mmcHint = "always-stale" + v.libraries.append(liteloader_lib) + + versions.append(v) + lookup[v.version] = v + + if latest_version: + latest = lookup[latest_version] return versions, latest -allVersions = [] -recommended = [] -for mcVersion, versionObject in remoteVersionlist.versions.items(): - # ignore this for now. It should be a jar mod or something. - if mcVersion == "1.5.2": - continue - latestSnapshot = None - latestRelease = None - version = [] - if versionObject.artefacts: - versions, latestRelease = processArtefacts(mcVersion, versionObject.artefacts.liteloader, True) - allVersions.extend(versions) - if versionObject.snapshots: - versions, latestSnapshot = processArtefacts(mcVersion, versionObject.snapshots.liteloader, False) - allVersions.extend(versions) +def process_versions(index: LiteloaderIndex) -> Tuple[List[MetaVersion], List[str]]: + all_versions: List[MetaVersion] = [] + recommended: List[str] = [] + for mcVersion, versionObject in index.versions.items(): + # ignore this for now. It should be a jar mod or something. + if mcVersion == "1.5.2": + continue - if latestRelease: - recommended.append(latestRelease.version) + latest_release = None + if versionObject.artefacts: + versions, latest_release = process_artefacts(mcVersion, versionObject.artefacts.liteloader, False) + all_versions.extend(versions) + if versionObject.snapshots: + versions, latest_snapshot = process_artefacts(mcVersion, versionObject.snapshots.liteloader, True) + all_versions.extend(versions) -recommended.sort() + if latest_release: + recommended.append(latest_release.version) -allVersions.sort(key=lambda x: x.releaseTime, reverse=True) + recommended.sort() -for version in allVersions: - outFilepath = PMC_DIR + "/com.mumfrey.liteloader/%s.json" % version.version - with open(outFilepath, 'w') as outfile: - json.dump(version.to_json(), outfile, sort_keys=True, indent=4) + all_versions.sort(key=lambda x: x.release_time, reverse=True) + return all_versions, recommended -sharedData = PolyMCSharedPackageData(uid='com.mumfrey.liteloader', name='LiteLoader') -sharedData.recommended = recommended -sharedData.description = remoteVersionlist.meta.description -sharedData.projectUrl = remoteVersionlist.meta.url -sharedData.authors = [remoteVersionlist.meta.authors] -sharedData.write() + +def main(): + index = LiteloaderIndex.parse_file(os.path.join(UPSTREAM_DIR, VERSIONS_FILE)) + + all_versions, recommended = process_versions(index) + + for version in all_versions: + version.write(os.path.join(PMC_DIR, LITELOADER_COMPONENT, f"{version.version}.json")) + + package = MetaPackage(uid=LITELOADER_COMPONENT, + name='LiteLoader', + description=index.meta.description, + project_url=index.meta.url, + authors=[index.meta.authors], + recommended=recommended) + package.write(os.path.join(PMC_DIR, LITELOADER_COMPONENT, "package.json")) + + +if __name__ == '__main__': + main() diff --git a/meta/common/liteloader.py b/meta/common/liteloader.py new file mode 100644 index 0000000..7a6c19e --- /dev/null +++ b/meta/common/liteloader.py @@ -0,0 +1,7 @@ +from os.path import join + +BASE_DIR = "liteloader" + +VERSIONS_FILE = join(BASE_DIR, "versions.json") + +LITELOADER_COMPONENT = "com.mumfrey.liteloader" diff --git a/meta/liteloaderutil.py b/meta/liteloaderutil.py deleted file mode 100644 index dce6cb1..0000000 --- a/meta/liteloaderutil.py +++ /dev/null @@ -1,118 +0,0 @@ -from .metautil import * - -''' - "repo":{ - "stream":"RELEASE", - "type":"m2", - "url":"http:\/\/dl.liteloader.com\/repo\/", - "classifier":"" - }, -''' - - -class LiteloaderRepo(JsonObject): - stream = StringProperty(required=True) - type = StringProperty(required=True) - url = StringProperty(required=True) - classifier = StringProperty(required=True) - - -''' - "53639d52340479ccf206a04f5e16606f":{ - "tweakClass":"com.mumfrey.liteloader.launch.LiteLoaderTweaker", - "libraries":[ - { - "name":"net.minecraft:launchwrapper:1.5" - }, - { - "name":"net.sf.jopt-simple:jopt-simple:4.5" - }, - { - "name":"org.ow2.asm:asm-all:4.1" - } - ], - "stream":"RELEASE", - "file":"liteloader-1.5.2_01.jar", - "version":"1.5.2_01", - "md5":"53639d52340479ccf206a04f5e16606f", - "timestamp":"1367366420" - }, -''' - - -class LiteloaderArtefact(JsonObject): - tweakClass = StringProperty(required=True) - libraries = ListProperty(PolyMCLibrary, required=True) - stream = StringProperty(required=True) - file = StringProperty(required=True) - version = StringProperty(required=True) - build = StringProperty(default=None, exclude_if_none=True) - md5 = StringProperty(required=True) - timestamp = StringProperty(required=True) - srcJar = StringProperty(default=None, exclude_if_none=True) - mcpJar = StringProperty(default=None, exclude_if_none=True) - - -class LiteloaderDev(JsonObject): - fgVersion = StringProperty(default=None, exclude_if_none=True) - mappings = StringProperty(required=None, exclude_if_none=True) - mcp = StringProperty(default=None, exclude_if_none=True) - - -class LiteloaderArtefacts(JsonObject): - liteloader = DictProperty(LiteloaderArtefact, name="com.mumfrey:liteloader", required=True) - - -class LiteloaderSnapshot(LiteloaderArtefact): - lastSuccessfulBuild = IntegerProperty() - - -class LiteloaderSnapshots(JsonObject): - libraries = ListProperty(PolyMCLibrary, required=True) - liteloader = DictProperty(LiteloaderSnapshot, name="com.mumfrey:liteloader", required=True) - - -''' - "1.10.2":{ - "dev": { ... }, - "repo":{ ... }, - "artefacts":{ - "com.mumfrey:liteloader":{ }, - ... - }, - "snapshots":{ - ... - } -''' - - -class LiteloaderEntry(JsonObject): - dev = ObjectProperty(LiteloaderDev, default=None, exclude_if_none=True) - repo = ObjectProperty(LiteloaderRepo, required=True) - artefacts = ObjectProperty(LiteloaderArtefacts, default=None, exclude_if_none=True) - snapshots = ObjectProperty(LiteloaderSnapshots, default=None, exclude_if_none=True) - - -''' - "meta":{ - "description":"LiteLoader is a lightweight mod bootstrap designed to provide basic loader functionality for mods which don't need to modify game mechanics.", - "authors":"Mumfrey", - "url":"http:\/\/dl.liteloader.com", - "updated":"2017-02-22T11:34:07+00:00", - "updatedTime":1487763247 - }, -''' - - -class LiteloaderMeta(JsonObject): - description = StringProperty(required=True) - authors = StringProperty(required=True) - url = StringProperty(required=True) - updated = ISOTimestampProperty(required=True) - updatedTime = IntegerProperty(required=True) - - -# The raw Forge version index -class LiteloaderIndex(JsonObject): - meta = ObjectProperty(LiteloaderMeta, required=True) - versions = DictProperty(LiteloaderEntry) diff --git a/meta/model/liteloader.py b/meta/model/liteloader.py new file mode 100644 index 0000000..0bd6794 --- /dev/null +++ b/meta/model/liteloader.py @@ -0,0 +1,108 @@ +from datetime import datetime +from typing import Optional, List, Dict, Any + +from pydantic import Field + +from . import Library, MetaBase + + +class LiteloaderDev(MetaBase): + fgVersion: Optional[str] + mappings: Optional[str] + mcp: Optional[str] + + +class LiteloaderRepo(MetaBase): + """ + "repo":{ + "stream":"RELEASE", + "type":"m2", + "url":"http://dl.liteloader.com/repo/", + "classifier":"" + }, + """ + stream: str + type: str + url: str + classifier: str + + +class LiteloaderArtefact(MetaBase): + """ + "53639d52340479ccf206a04f5e16606f":{ + "tweakClass":"com.mumfrey.liteloader.launch.LiteLoaderTweaker", + "libraries":[ + { + "name":"net.minecraft:launchwrapper:1.5" + }, + { + "name":"net.sf.jopt-simple:jopt-simple:4.5" + }, + { + "name":"org.ow2.asm:asm-all:4.1" + } + ], + "stream":"RELEASE", + "file":"liteloader-1.5.2_01.jar", + "version":"1.5.2_01", + "md5":"53639d52340479ccf206a04f5e16606f", + "timestamp":"1367366420" + }, + """ + tweakClass: str + libraries: List[Library] + stream: str + file: str + version: str + build: Optional[str] + md5: str + timestamp: str + srcJar: Optional[str] + mcpJar: Optional[str] + lastSuccessfulBuild: Optional[int] # only for snapshots + + +class LiteloaderArtefacts(MetaBase): + liteloader: Dict[str, LiteloaderArtefact] = Field(alias="com.mumfrey:liteloader") + libraries: Optional[List[Library]] + + +class LiteloaderEntry(MetaBase): + """ + "1.10.2":{ + "dev": { ... }, + "repo":{ ... }, + "artefacts":{ + "com.mumfrey:liteloader":{ }, + ... + }, + "snapshots":{ + ... + } + """ + dev: Optional[LiteloaderDev] + repo: LiteloaderRepo + artefacts: Optional[LiteloaderArtefacts] + snapshots: Optional[LiteloaderArtefacts] + + +class LiteloaderMeta(MetaBase): + """ + "meta":{ + "description":"LiteLoader is a lightweight mod bootstrap designed to provide basic loader functionality for mods which don't need to modify game mechanics.", + "authors":"Mumfrey", + "url":"http://dl.liteloader.com", + "updated":"2017-02-22T11:34:07+00:00", + "updatedTime":1487763247 + }, + """ + description: str + authors: str + url: str + updated: datetime + updated_time: int = Field(alias="updatedTime") + + +class LiteloaderIndex(MetaBase): + meta: LiteloaderMeta + versions: Dict[Any, LiteloaderEntry] diff --git a/updateLiteloader.py b/updateLiteloader.py index 2add518..e4d09fa 100755 --- a/updateLiteloader.py +++ b/updateLiteloader.py @@ -1,37 +1,40 @@ -''' - Get the source files necessary for generating Forge versions -''' -import copy -import sys +import json +import os import requests from cachecontrol import CacheControl from cachecontrol.caches import FileCache -from meta.liteloaderutil import * -UPSTREAM_DIR = os.environ["UPSTREAM_DIR"] - - -def eprint(*args, **kwargs): - print(*args, file=sys.stderr, **kwargs) +from meta.common import upstream_path +from meta.common.liteloader import VERSIONS_FILE +from meta.model.liteloader import LiteloaderIndex +UPSTREAM_DIR = upstream_path() forever_cache = FileCache('caches/http_cache', forever=True) sess = CacheControl(requests.Session(), forever_cache) -# get the remote version list -r = sess.get('http://dl.liteloader.com/versions/versions.json') -r.raise_for_status() -# make sure it's JSON -main_json = r.json() +def main(): + # get the remote version list + r = sess.get('http://dl.liteloader.com/versions/versions.json') + r.raise_for_status() -# make sure we understand the schema -remoteVersionlist = LiteloaderIndex(copy.deepcopy(main_json)) -newStr = json.dumps(remoteVersionlist.to_json(), sort_keys=True) -origStr = json.dumps(main_json, sort_keys=True) -assert newStr == origStr + # make sure it's JSON + main_json = r.json() -# save the json it to file -with open(UPSTREAM_DIR + "/liteloader/versions.json", 'w', encoding='utf-8') as f: - json.dump(main_json, f, sort_keys=True, indent=4) + # make sure we understand the schema + remote_versions = LiteloaderIndex.parse_obj(main_json) + parsed = remote_versions.json() + original = json.dumps(main_json, sort_keys=True, indent=4) + assert parsed == original + + print("Successfully parsed index") + print(f"Last updated {remote_versions.meta.updated}") + + # save the json it to file + remote_versions.write(os.path.join(UPSTREAM_DIR, VERSIONS_FILE)) + + +if __name__ == '__main__': + main()