feat: build profile for The Only Doe 0.05 that fixes an assignment in a menu condition
sleep.rpy tests `... before_sleeping=2` (assignment) in an elif; sleep.rpyc holds the same text, so Ren'Py cannot compile that branch either. Builds can now carry exact-line patches pinned by the SHA-256 of the line and the build fingerprint; this one restores `==2`. Anything else stays strict. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
4dc9836a8b
commit
0822c76321
2 files changed
+45
No files matched your search
@@ -90,6 +90,18 @@ BUILDS: dict[str, dict] = {
|
|||||||
},
|
},
|
||||||
"defects": {},
|
"defects": {},
|
||||||
},
|
},
|
||||||
|
"bb19a33af00324fa027a629c052aee885e72f1b7bee7074403a5b9e20c69e2d8": {
|
||||||
|
"id": "renpy/the-only-doe-0.05",
|
||||||
|
# One menu branch tests `... before_sleeping=2` (assignment), which Ren'Py cannot compile either:
|
||||||
|
# sleep.rpyc holds the same text. The port corrects the operator; the digest pins the exact line.
|
||||||
|
"lines": {
|
||||||
|
"sleep.rpy": {
|
||||||
|
"fa092f95dd51401da31285c68c7c4fa9ad9ae4a5dd8c1a1582192f32b1e650cf":
|
||||||
|
' elif wake_up_after_sex=="spitroast" and number_of_people_had_sex_with_before_sleeping==2:',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"defects": {},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -136,6 +148,19 @@ def identify(game_dir: Path) -> str | None:
|
|||||||
return build["id"] if build else None
|
return build["id"] if build else None
|
||||||
|
|
||||||
|
|
||||||
|
def _patch_lines(source: str, patches: dict[str, str]) -> str:
|
||||||
|
"""Replace single lines whose exact text (without the line ending) matches a recorded SHA-256."""
|
||||||
|
if not patches:
|
||||||
|
return source
|
||||||
|
lines = source.splitlines(keepends=True)
|
||||||
|
for index, line in enumerate(lines):
|
||||||
|
text = line.rstrip("\r\n")
|
||||||
|
replacement = patches.get(hashlib.sha256(text.encode()).hexdigest())
|
||||||
|
if replacement is not None:
|
||||||
|
lines[index] = replacement + line[len(text):]
|
||||||
|
return "".join(lines)
|
||||||
|
|
||||||
|
|
||||||
def prepare_source(build_id: str | None, relative: str, source: str) -> str:
|
def prepare_source(build_id: str | None, relative: str, source: str) -> str:
|
||||||
"""Adapt verified engine integration blocks, preserving source line numbers.
|
"""Adapt verified engine integration blocks, preserving source line numbers.
|
||||||
|
|
||||||
@@ -145,6 +170,7 @@ def prepare_source(build_id: str | None, relative: str, source: str) -> str:
|
|||||||
from app.converter.rpy_lexer import parse_tree
|
from app.converter.rpy_lexer import parse_tree
|
||||||
|
|
||||||
build = next((b for b in BUILDS.values() if b["id"] == build_id), {})
|
build = next((b for b in BUILDS.values() if b["id"] == build_id), {})
|
||||||
|
source = _patch_lines(source, build.get("lines", {}).get(relative.lower(), {}))
|
||||||
patches = build.get("blocks", {}).get(relative.lower(), {})
|
patches = build.get("blocks", {}).get(relative.lower(), {})
|
||||||
if not patches:
|
if not patches:
|
||||||
return source
|
return source
|
||||||
|
|||||||
@@ -52,3 +52,22 @@ def test_known_defects_are_waived_only_up_to_the_recorded_count():
|
|||||||
assert blocking == [new] and known == [known_issue]
|
assert blocking == [new] and known == [known_issue]
|
||||||
same_message_other_script = Issue(code, message, "SomewhereElse:1")
|
same_message_other_script = Issue(code, message, "SomewhereElse:1")
|
||||||
assert split_known([same_message_other_script])[0] == [same_message_other_script]
|
assert split_known([same_message_other_script])[0] == [same_message_other_script]
|
||||||
|
|
||||||
|
|
||||||
|
def test_known_build_line_patch_requires_the_exact_line():
|
||||||
|
import hashlib
|
||||||
|
|
||||||
|
from app.games import renpy_builds
|
||||||
|
|
||||||
|
wrong = ' elif wake_up_after_sex=="spitroast" and number_of_people_had_sex_with_before_sleeping=2:'
|
||||||
|
fixed = wrong.replace("=2:", "==2:")
|
||||||
|
assert hashlib.sha256(wrong.encode()).hexdigest() in renpy_builds.BUILDS[
|
||||||
|
"bb19a33af00324fa027a629c052aee885e72f1b7bee7074403a5b9e20c69e2d8"]["lines"]["sleep.rpy"]
|
||||||
|
source = f"label a:\r\n{wrong}\r\n pass\r\n"
|
||||||
|
assert renpy_builds.prepare_source("renpy/the-only-doe-0.05", "Sleep.rpy", source) == \
|
||||||
|
f"label a:\r\n{fixed}\r\n pass\r\n"
|
||||||
|
# another build, another file, or an edited line stays untouched
|
||||||
|
assert renpy_builds.prepare_source(None, "sleep.rpy", source) == source
|
||||||
|
assert renpy_builds.prepare_source("renpy/the-only-doe-0.05", "other.rpy", source) == source
|
||||||
|
edited = source.replace("spitroast", "other")
|
||||||
|
assert renpy_builds.prepare_source("renpy/the-only-doe-0.05", "sleep.rpy", edited) == edited
|
||||||
Reference in new issue
Block a user