Fix game support not updating when removing a provided mod

This commit is contained in:
rubenwardy 2024-03-29 15:54:39 +00:00
parent 311d07d454
commit b33a7f79b1
3 changed files with 51 additions and 8 deletions

@ -213,7 +213,7 @@ class GameSupport:
package.is_confirmed = True
return package.supported_games
def on_update(self, package: GSPackage):
def on_update(self, package: GSPackage, old_provides: Optional[set[str]] = None):
to_update = {package}
checked = set()
@ -224,7 +224,11 @@ class GameSupport:
current_package.detected_supported_games = []
self._get_supported_games(current_package, [])
for modname in current_package.provides:
provides = current_package.provides
if current_package == package and old_provides is not None:
provides = provides.union(old_provides)
for modname in provides:
for depending_package in self.get_all_that_depend_on(modname):
if depending_package not in checked:
to_update.add(depending_package)
@ -310,12 +314,12 @@ def _persist(session: sqlalchemy.orm.Session, support: GameSupport):
session.add(new_support)
def game_support_update(session: sqlalchemy.orm.Session, package: Package) -> set[str]:
def game_support_update(session: sqlalchemy.orm.Session, package: Package, old_provides: Optional[set[str]]) -> set[str]:
support = _create_instance(session)
gs_package = support.get(package.get_id())
if gs_package is None:
gs_package = _convert_package(support, package)
support.on_update(gs_package)
support.on_update(gs_package, old_provides)
_persist(session, support)
return gs_package.errors

@ -97,7 +97,7 @@ def update_all_game_support():
@celery.task()
def update_package_game_support(package_id: int):
package = Package.query.get(package_id)
game_support_update(db.session, package)
game_support_update(db.session, package, None)
db.session.commit()
@ -123,14 +123,14 @@ def post_release_check_update(self, release: PackageRelease, path):
provides = tree.get_mod_names()
package = release.package
old_modnames = set([x.name for x in package.provides])
old_provided_names = set([x.name for x in package.provides])
package.provides.clear()
# If new mods were added, add to audit log
if package.state == PackageState.APPROVED:
new_provides = []
for modname in provides:
if modname not in old_modnames:
if modname not in old_provided_names:
new_provides.append(modname)
if len(new_provides) > 0:
@ -218,7 +218,7 @@ def post_release_check_update(self, release: PackageRelease, path):
game_support_set(db.session, package, game_is_supported, 10)
if package.type == PackageType.MOD:
errors = game_support_update(db.session, package)
errors = game_support_update(db.session, package, old_provided_names)
if len(errors) != 0:
raise TaskError("Error validating game support:\n\n" + "\n".join([f"- {x}" for x in errors]))

@ -313,6 +313,45 @@ def test_update_new_mod():
assert len(lib.detected_supported_games) == 0
def test_update_remove_mod():
"""
Test that removing a mod from provides will update mods that depended on the modname
"""
support = GameSupport()
support.add(make_game("game1", ["default"]))
game2 = support.add(make_game("game2", ["core", "mod_b"]))
modB = support.add(make_mod("mod_b", ["mod_b"], ["default"]))
lib = support.add(make_mod("lib", ["lib"], []))
modA = support.add(make_mod("mod_a", ["mod_a"], ["mod_b", "lib"]))
support.on_first_run()
assert not support.has_errors
assert modA.is_confirmed
assert modA.detected_supported_games == {"game1", "game2"}
assert modB.is_confirmed
assert modB.detected_supported_games == {"game1"}
assert lib.is_confirmed
assert len(lib.detected_supported_games) == 0
old_provides = game2.provides.copy()
game2.provides.remove("mod_b")
support.on_update(game2, old_provides)
assert not support.has_errors
assert modA.is_confirmed
assert modA.detected_supported_games == {"game1"}
assert modB.is_confirmed
assert modB.detected_supported_games == {"game1"}
assert lib.is_confirmed
assert len(lib.detected_supported_games) == 0
def test_update_cycle():
"""
Test that updating a package with a cycle depending on it doesn't break