Skip to content

Commit

Permalink
add archive for new mods and txt file for deleted mods
Browse files Browse the repository at this point in the history
  • Loading branch information
boubou19 committed Dec 6, 2024
1 parent fbee494 commit 4b353d1
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 27 deletions.
13 changes: 9 additions & 4 deletions src/gtnh/assembler/generic_assembler.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,46 +121,51 @@ def get_mods(self, side: Side) -> List[Tuple[GTNHModInfo, GTNHVersion]]:
mods: List[Tuple[GTNHModInfo, GTNHVersion]] = github_mods + external_mods
return mods

def external_mods(self, valid_sides: Set[Side]) -> List[Tuple[GTNHModInfo, GTNHVersion]]:
def external_mods(self, valid_sides: Set[Side], release:Optional[GTNHRelease]=None) -> List[Tuple[GTNHModInfo, GTNHVersion]]:
"""
Method to grab the external mod info objects as well as their targetted version.
:param valid_sides: a set of valid sides to retrieve the mods from.
:param release: if specified, the release version to get data from instead of the one used for the assembling.
"""
get_mod: Callable[
[str, ModVersionInfo, Set[Side], ModSource],
Optional[tuple[Union[GTNHModInfo], GTNHVersion]],
] = self.modpack_manager.assets.get_mod_and_version

release = self.release if release is None else release

external_mods: List[Tuple[GTNHModInfo, GTNHVersion]] = list(
filter(
None,
[
get_mod(name, version, valid_sides, ModSource.other)
for name, version in self.release.external_mods.items()
for name, version in release.external_mods.items()
],
)
)

return external_mods

def github_mods(self, valid_sides: Set[Side]) -> List[Tuple[GTNHModInfo, GTNHVersion]]:
def github_mods(self, valid_sides: Set[Side], release:Optional[GTNHRelease]=None) -> List[Tuple[GTNHModInfo, GTNHVersion]]:
"""
Method to grab the github mod info objects as well as their targetted version.
:param valid_sides: a set of valid sides to retrieve the mods from.
:param release: if specified, the release version to get data from instead of the one used for the assembling.
"""
get_mod: Callable[
[str, ModVersionInfo, Set[Side], ModSource],
Optional[tuple[GTNHModInfo, GTNHVersion]],
] = self.modpack_manager.assets.get_mod_and_version
release = self.release if release is None else release

github_mods: List[Tuple[GTNHModInfo, GTNHVersion]] = list(
filter(
None,
[
get_mod(name, version, valid_sides, ModSource.github)
for name, version in self.release.github_mods.items()
for name, version in release.github_mods.items()
],
)
)
Expand Down
86 changes: 65 additions & 21 deletions src/gtnh/assembler/technic.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import os
import re
import shutil
from enum import Enum
from pathlib import Path
from typing import Callable, List, Optional, Set, Tuple
from zipfile import ZIP_DEFLATED, ZipFile
Expand All @@ -20,6 +21,12 @@
log = get_logger("technic process")


class DifferentialUpdateMode(str, Enum):
NEW_MODS = "NEW_MODS"
UPDATED_MODS = "UPDATED_MODS"
REMOVED_MODS = "REMOVED_MODS"


def technify(string: str) -> str:
"""
format the given string to be only lower case letters or numbers or dashes.
Expand Down Expand Up @@ -76,51 +83,82 @@ async def partial_assemble(self, side: Side, verbose: bool = False) -> None:
if side not in {Side.CLIENT, Side.CLIENT_JAVA9}:
raise Exception(f"Can only assemble release for CLIENT or SERVER, not {side}")

archive_name: Path = self.get_partial_archive_path()
updated_mods_archive_name: Path = self.get_updated_mods_archive_path()
new_mods_archive_name: Path = self.get_new_mods_archive_path()
removed_modlist_name: Path = self.get_removed_modlist_path()

# deleting any existing archive
if os.path.exists(archive_name):
os.remove(archive_name)
log.warn(f"Previous archive {Fore.YELLOW}'{archive_name}'{Fore.RESET} deleted")
if os.path.exists(updated_mods_archive_name):
os.remove(updated_mods_archive_name)
log.warn(f"Previous archive {Fore.YELLOW}'{updated_mods_archive_name}'{Fore.RESET} deleted")

if os.path.exists(new_mods_archive_name):
os.remove(new_mods_archive_name)
log.warn(f"Previous archive {Fore.YELLOW}'{new_mods_archive_name}'{Fore.RESET} deleted")

log.info(f"Constructing {Fore.YELLOW}{side}{Fore.RESET} archive at {Fore.YELLOW}'{archive_name}'{Fore.RESET}")
if os.path.exists(removed_modlist_name):
os.remove(removed_modlist_name)
log.warn(f"Previous modlist {Fore.YELLOW}'{removed_modlist_name}'{Fore.RESET} deleted")

with ZipFile(archive_name, "w", compression=ZIP_DEFLATED) as archive:
log.info(f"Constructing {Fore.YELLOW}{side}{Fore.RESET} archive at {Fore.YELLOW}'{updated_mods_archive_name}'{Fore.RESET}")

with ZipFile(updated_mods_archive_name, "w", compression=ZIP_DEFLATED) as archive:
log.info("Adding mods to the archive")
self.add_mods(side, self.partial_mods(side), archive, verbose=verbose)
self.add_mods(side, self.differential_update(side, DifferentialUpdateMode.UPDATED_MODS), archive, verbose=verbose)
log.info("Adding config to the archive")
self.add_config(side, self.get_config(), archive, verbose=verbose)
log.info("Generating the readme for the modpack repo")
self.generate_readme()
log.info("Archive created successfully!")

def partial_mods(self, side: Side) -> list[Tuple[GTNHModInfo, GTNHVersion]]:
log.info(f"Constructing {Fore.YELLOW}{side}{Fore.RESET} archive at {Fore.YELLOW}'{new_mods_archive_name}'{Fore.RESET}")

with ZipFile(new_mods_archive_name, "w", compression=ZIP_DEFLATED) as archive:
log.info("Adding mods to the archive")
self.add_mods(side, self.differential_update(side, DifferentialUpdateMode.NEW_MODS), archive, verbose=verbose)
log.info("Archive created successfully!")

with open(removed_modlist_name, "w") as file:
log.info("generating removed modlist")
removed_modlist: List[tuple[GTNHModInfo, GTNHVersion]] = self.differential_update(side, DifferentialUpdateMode.REMOVED_MODS)
file.write("\n".join([f"{mod.name}: {version.version_tag}" for (mod, version) in removed_modlist]))
log.info("modlist created successfully!")

def differential_update(self, side: Side, update_mode:DifferentialUpdateMode) -> list[Tuple[GTNHModInfo, GTNHVersion]]:
update_source: Callable[[GTNHRelease, GTNHRelease], set[str]]

if update_mode == DifferentialUpdateMode.NEW_MODS:
update_source = self.modpack_manager.get_new_mods
elif update_mode == DifferentialUpdateMode.UPDATED_MODS:
update_source = self.modpack_manager.get_changed_mods
else:
update_source = self.modpack_manager.get_removed_mods

last_release: GTNHRelease = self.modpack_manager.get_release(self.release.last_version) # type: ignore
process_release: GTNHRelease = last_release if update_mode == DifferentialUpdateMode.REMOVED_MODS else self.release

valid_sides: Set[Side] = side.valid_mod_sides()
j9_sides: Set[Side] = {Side.CLIENT_JAVA9, Side.BOTH_JAVA9}

github_mods: List[Tuple[GTNHModInfo, GTNHVersion]] = self.github_mods(valid_sides)
github_mods: List[Tuple[GTNHModInfo, GTNHVersion]] = self.github_mods(valid_sides, release=process_release)
github_mods_names = [x[0].name for x in github_mods]
github_mods_j9: List[Tuple[GTNHModInfo, GTNHVersion]] = self.github_mods(j9_sides)
github_mods_j9: List[Tuple[GTNHModInfo, GTNHVersion]] = self.github_mods(j9_sides, release=process_release)
github_mods_names_j9 = [x[0].name for x in github_mods_j9]

external_mods: List[Tuple[GTNHModInfo, GTNHVersion]] = self.external_mods(valid_sides)
external_mods: List[Tuple[GTNHModInfo, GTNHVersion]] = self.external_mods(valid_sides, release=process_release)
external_mods_names = [x[0].name for x in external_mods]
external_mods_j9: List[Tuple[GTNHModInfo, GTNHVersion]] = self.external_mods(j9_sides)
external_mods_j9: List[Tuple[GTNHModInfo, GTNHVersion]] = self.external_mods(j9_sides, release=process_release)
external_mods_names_j9 = [x[0].name for x in external_mods_j9]

last_version: GTNHRelease = self.modpack_manager.get_release(self.release.last_version) # type: ignore

mods: List[Tuple[GTNHModInfo, GTNHVersion]] = []

for mod_name in self.modpack_manager.get_changed_mods(self.release, last_version):
for mod_name in update_source(self.release, last_release):
if mod_name in github_mods_names:
mod_index = github_mods_names.index(mod_name)
mods.append(github_mods[mod_index])
elif mod_name in external_mods_names:
mod_index = external_mods_names.index(mod_name)
mods.append(external_mods[mod_index])
else:

if side == Side.CLIENT and (mod_name in github_mods_names_j9 or mod_name in external_mods_names_j9):
log.warn(f"Mod {mod_name} is a java 9+ mod but currently packing only java 8 mods. Skipping it.")
else:
Expand All @@ -134,7 +172,7 @@ def add_mods(
self, side: Side, mods: list[tuple[GTNHModInfo, GTNHVersion]], archive: ZipFile, verbose: bool = False
) -> None:

temp_zip_path: Path = Path("./temp.zip")
temp_zip_path: Path = RELEASE_TECHNIC_DIR / "temp.zip"

for mod, version in mods:
source_file: Path = get_asset_version_cache_location(mod, version)
Expand All @@ -155,7 +193,7 @@ def add_mods(
)

# deleting temp zip
if temp_zip_path is not None:
if temp_zip_path.exists():
temp_zip_path.unlink()

def add_config(
Expand Down Expand Up @@ -213,8 +251,14 @@ def add_config(
def get_archive_path(self, side: Side) -> Path:
return RELEASE_TECHNIC_DIR / f"GT_New_Horizons_{self.release.version}_(technic).zip"

def get_partial_archive_path(self) -> Path:
return RELEASE_TECHNIC_DIR / f"GT_New_Horizons_{self.release.version}_(technic_partial).zip"
def get_updated_mods_archive_path(self) -> Path:
return RELEASE_TECHNIC_DIR / f"GT_New_Horizons_{self.release.version}_(updated mods).zip"

def get_new_mods_archive_path(self) -> Path:
return RELEASE_TECHNIC_DIR / f"GT_New_Horizons_{self.release.version}_(new mods).zip"

def get_removed_modlist_path(self) -> Path:
return RELEASE_TECHNIC_DIR / f"GT_New_Horizons_{self.release.version}_(removed mods).txt"

async def assemble(self, side: Side, verbose: bool = False) -> None:
if side != Side.CLIENT:
Expand Down
40 changes: 38 additions & 2 deletions src/gtnh/modpack_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -967,12 +967,48 @@ def remove_false_positive_in_mod_removed(cls, removed_mods: Set[str], added_mods
for false_positive in false_added_mods:
added_mods.remove(false_positive)

def get_removed_mods(self, release: GTNHRelease, previous_release: GTNHRelease) -> Set[str]:
"""
Generate the list of removed mods between two releases.
:returns: set[str]
"""
removed_mods = set()
new_mods = set()

removed_mods |= set(previous_release.github_mods.keys() - release.github_mods.keys())
removed_mods |= set(previous_release.external_mods.keys() - release.external_mods.keys())

new_mods |= set(release.github_mods.keys() - previous_release.github_mods.keys())
new_mods |= set(release.external_mods.keys() - previous_release.external_mods.keys())

self.remove_false_positive_in_mod_removed(removed_mods, new_mods)
return removed_mods

def get_new_mods(self, release: GTNHRelease, previous_release: GTNHRelease) -> Set[str]:
"""
Generate the list of new mods between two releases.
:returns: set[str]
"""
removed_mods = set()
new_mods = set()

removed_mods |= set(previous_release.github_mods.keys() - release.github_mods.keys())
removed_mods |= set(previous_release.external_mods.keys() - release.external_mods.keys())

new_mods |= set(release.github_mods.keys() - previous_release.github_mods.keys())
new_mods |= set(release.external_mods.keys() - previous_release.external_mods.keys())

self.remove_false_positive_in_mod_removed(removed_mods, new_mods)
return new_mods

def get_changed_mods(self, release: GTNHRelease, previous_release: GTNHRelease) -> Set[str]:
"""
Generate the list of updated/added mods between two releases. If the `previous_release` is None, generate
it for all of history.
it for all history.
:returns: dict[mod_name, list[version_changes]]
:returns: set[str]
"""
removed_mods = set()
new_mods = set()
Expand Down

0 comments on commit 4b353d1

Please sign in to comment.