Core: Fix Template Yamls for games with colon in name (#4106)

* add quotes around strings containing {{ game }}

* do the actually correct thing instead of a hack

thanks berserker66 for pointing out to me that I was doing this the
completly wrong way, so I fixed it up

* Clean up filenames to prevent illegal chars

* Use %s substitution instead of concatenation

* whoops

somehow i removed a space from the comment for the regex, so this adds
it back

* Use pre-existing function in Utils.py

* Test: add test for option yaml with colon

---------

Co-authored-by: black-sliver <59490463+black-sliver@users.noreply.github.com>
This commit is contained in:
gurglemurgle5 2024-11-14 16:43:42 -06:00 committed by GitHub
parent dd659de079
commit 6c9b7eca10
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 60 additions and 5 deletions

View File

@ -15,7 +15,7 @@ from dataclasses import dataclass
from schema import And, Optional, Or, Schema
from typing_extensions import Self
from Utils import get_fuzzy_results, is_iterable_except_str, output_path
from Utils import get_file_safe_name, get_fuzzy_results, is_iterable_except_str, output_path
if typing.TYPE_CHECKING:
from BaseClasses import MultiWorld, PlandoOptions
@ -1531,7 +1531,7 @@ def generate_yaml_templates(target_folder: typing.Union[str, "pathlib.Path"], ge
del file_data
with open(os.path.join(target_folder, game_name + ".yaml"), "w", encoding="utf-8-sig") as f:
with open(os.path.join(target_folder, get_file_safe_name(game_name) + ".yaml"), "w", encoding="utf-8-sig") as f:
f.write(res)

View File

@ -28,9 +28,9 @@
name: Player{number}
# Used to describe your yaml. Useful if you have multiple files.
description: Default {{ game }} Template
description: {{ yaml_dump("Default %s Template" % game) }}
game: {{ game }}
game: {{ yaml_dump(game) }}
requires:
version: {{ __version__ }} # Version of Archipelago required for this yaml to work as expected.
@ -44,7 +44,7 @@ requires:
{%- endfor -%}
{% endmacro %}
{{ game }}:
{{ yaml_dump(game) }}:
{%- for group_name, group_options in option_groups.items() %}
# {{ group_name }}

View File

@ -0,0 +1,55 @@
import unittest
from pathlib import Path
from tempfile import TemporaryDirectory
from typing import TYPE_CHECKING, Dict, Type
from Utils import parse_yaml
if TYPE_CHECKING:
from worlds.AutoWorld import World
class TestGenerateYamlTemplates(unittest.TestCase):
old_world_types: Dict[str, Type["World"]]
def setUp(self) -> None:
import worlds.AutoWorld
self.old_world_types = worlds.AutoWorld.AutoWorldRegister.world_types
def tearDown(self) -> None:
import worlds.AutoWorld
worlds.AutoWorld.AutoWorldRegister.world_types = self.old_world_types
if "World: with colon" in worlds.AutoWorld.AutoWorldRegister.world_types:
del worlds.AutoWorld.AutoWorldRegister.world_types["World: with colon"]
def test_name_with_colon(self) -> None:
from Options import generate_yaml_templates
from worlds.AutoWorld import AutoWorldRegister
from worlds.AutoWorld import World
class WorldWithColon(World):
game = "World: with colon"
item_name_to_id = {}
location_name_to_id = {}
AutoWorldRegister.world_types = {WorldWithColon.game: WorldWithColon}
with TemporaryDirectory(f"archipelago_{__name__}") as temp_dir:
generate_yaml_templates(temp_dir)
path: Path
for path in Path(temp_dir).iterdir():
self.assertTrue(path.is_file())
self.assertTrue(path.suffix == ".yaml")
with path.open(encoding="utf-8") as f:
try:
data = parse_yaml(f)
except:
f.seek(0)
print(f"Error in {path.name}:\n{f.read()}")
raise
self.assertIn("game", data)
self.assertIn(":", data["game"])
self.assertIn(data["game"], data)
self.assertIsInstance(data[data["game"]], dict)