mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-11-06 10:03:49 -06:00
fix: keep release notes to checked claims
The v2026.10.10 notes said a pack holds every file its emulators open, so a game never stops on a missing file, and that hashes never come from a forum list: the gap analysis lists files no pack carries, and in md5 mode a pack keeps the platform's own md5 (verification-modes.md). The generated text and the README now point to the gap analysis, and release_notes.py refuses a whats-new text holding a judging or contradicted phrase.
This commit is contained in:
1 parent
fd3733fcaa
commit
556855421a
5 files changed
+62
-6
No files matched your search
@@ -43,7 +43,7 @@ First time? Follow the [first install, step by step](https://abdess.github.io/re
|
||||
|
||||
## Download BIOS packs
|
||||
|
||||
A pack holds everything its platform runs: its own BIOS list plus every file its emulator cores load. Pick your platform, download the ZIP, extract to the BIOS path. Each Download link is a page that keeps its address from one release to the next. The installer above does the same file by file: its screen installs everything, or fewer under **Choose systems**, and `--system`, `--core`, `--region` and `--target` make the same choice without questions. For a bare minimum, build your own pack below.
|
||||
A pack holds its platform's own BIOS list plus the files its emulator cores load. What no pack carries yet is in the [gap analysis](https://abdess.github.io/retrobios/gaps/). Pick your platform, download the ZIP, extract to the BIOS path. Each Download link is a page that keeps its address from one release to the next. The installer above does the same file by file: its screen installs everything, or fewer under **Choose systems**, and `--system`, `--core`, `--region` and `--target` make the same choice without questions. For a bare minimum, build your own pack below.
|
||||
|
||||
A pack over 2 GB comes in several parts (`Pack.part1of2.zip`, `Pack.part2of2.zip`), and every part is needed. Each part is an ordinary ZIP: extract them all into the same folder.
|
||||
|
||||
@@ -208,4 +208,4 @@ The scripts and tooling are released under the [MIT License](LICENSE).
|
||||
The BIOS and firmware files are not covered by that license: they are third-party system software, preserved and provided for personal backup, archival, and interoperability with emulation software. [NOTICE](NOTICE) sets out their status and how to ask for a file to be removed.
|
||||
The reasoning, and where it is weakest, is in [the project's legal position](https://abdess.github.io/retrobios/wiki/legal/).
|
||||
|
||||
*Auto-generated on 2026-11-06T05:38:30Z*
|
||||
*Auto-generated on 2026-11-06T07:24:52Z*
|
||||
@@ -608,7 +608,7 @@ def generate_readme(db: dict, platforms_dir: str, db_path: str = "database.json"
|
||||
"",
|
||||
"## Download BIOS packs",
|
||||
"",
|
||||
"A pack holds everything its platform runs: its own BIOS list plus every file its emulator cores load. Pick your platform, download the ZIP, extract to the BIOS path. Each Download link is a page that keeps its address from one release to the next. The installer above does the same file by file: its screen installs everything, or fewer under **" + _installer_words().TUI_SYSTEMS_ROW + "**, and `--system`, `--core`, `--region` and `--target` make the same choice without questions. For a bare minimum, build your own pack below.",
|
||||
f"A pack holds its platform's own BIOS list plus the files its emulator cores load. What no pack carries yet is in the [gap analysis]({SITE_URL}gaps/). Pick your platform, download the ZIP, extract to the BIOS path. Each Download link is a page that keeps its address from one release to the next. The installer above does the same file by file: its screen installs everything, or fewer under **" + _installer_words().TUI_SYSTEMS_ROW + "**, and `--system`, `--core`, `--region` and `--target` make the same choice without questions. For a bare minimum, build your own pack below.",
|
||||
"",
|
||||
"A pack over 2 GB comes in several parts (`Pack.part1of2.zip`,"
|
||||
" `Pack.part2of2.zip`), and every part is needed. Each part is an"
|
||||
|
||||
@@ -7,7 +7,8 @@ issue 81 happened. Install commands, the parts sentence and the table come
|
||||
from the record and the registry. Each row links the platform's page under
|
||||
get/ on the site, which outlives the release, and the setups the registry
|
||||
does not mark release_pack are named with the command. The maintainer writes
|
||||
what changed, and that text is appended as given.
|
||||
what changed, and that text is appended as given once it holds none of the
|
||||
REFUSED phrases.
|
||||
|
||||
Usage:
|
||||
python scripts/release_notes.py --whats-new tmp/whats-new.md --output notes.md
|
||||
@@ -102,6 +103,20 @@ def _link(name: str, pack: dict) -> str:
|
||||
return f"[{label}]({release_record.get_page(_owner(name, pack), SITE)})"
|
||||
|
||||
|
||||
# Words the published notes of v2026.10.10 carried by hand: "never from a
|
||||
# forum list" judged lists other people keep, and "a game never stops on a
|
||||
# missing file" was a claim the gap analysis contradicts. Text about other
|
||||
# projects says what changed, not who erred (wiki/release-process.md).
|
||||
REFUSED = ("their file", "theirs", "of ours", "corrected", "wrong", "drift",
|
||||
"left out", "never seen", "forum", "never stops", "never fails")
|
||||
|
||||
|
||||
def refused_words(text: str) -> list[str]:
|
||||
"""The refused phrases the text holds, case ignored."""
|
||||
lowered = text.lower()
|
||||
return [phrase for phrase in REFUSED if phrase in lowered]
|
||||
|
||||
|
||||
def render(record: dict, platforms_dir: str, whats_new: str) -> str:
|
||||
packs = record.get("packs", {})
|
||||
folders = _extract_folders(record, platforms_dir)
|
||||
@@ -124,7 +139,8 @@ def render(record: dict, platforms_dir: str, whats_new: str) -> str:
|
||||
"### Download a pack",
|
||||
"",
|
||||
("One complete pack for each platform below: the BIOS list the platform"
|
||||
" publishes plus every file its emulators open. Each link is a page"
|
||||
" publishes plus the files its emulators open. Files no pack carries yet"
|
||||
f" are listed in the [gap analysis]({SITE}gaps/). Each link is a page"
|
||||
" that keeps its address from one release to the next. Files is what the pack"
|
||||
" holds once extracted, the count a file manager shows. Extracted size"
|
||||
" is the space those files take, and the download is smaller."),
|
||||
@@ -173,6 +189,12 @@ def main() -> int:
|
||||
if not whats_new.strip():
|
||||
print(f"Error: {args.whats_new} is empty", file=sys.stderr)
|
||||
return 1
|
||||
refused = refused_words(whats_new)
|
||||
if refused:
|
||||
print(f"Error: {args.whats_new} says {', '.join(repr(w) for w in refused)}. State what"
|
||||
" changed and how it was checked, not a verdict on other projects or a"
|
||||
" promise the gap analysis contradicts", file=sys.stderr)
|
||||
return 1
|
||||
write_text_atomic(str(args.output), render(record, args.platforms_dir, whats_new))
|
||||
print(f"Wrote {args.output} for {record['tag']}, {len(record['packs'])} packs")
|
||||
return 0
|
||||
|
||||
@@ -11,12 +11,14 @@ installer fetches and leaves out the data directories a pack also carries.
|
||||
from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
import io
|
||||
import json
|
||||
import sys
|
||||
import tempfile
|
||||
import unittest
|
||||
import zipfile
|
||||
from pathlib import Path
|
||||
from unittest import mock
|
||||
|
||||
import yaml
|
||||
|
||||
@@ -552,6 +554,35 @@ class TheReleaseNotesReadTheRecord(unittest.TestCase):
|
||||
def test_the_notes_never_open_on_the_collection(self):
|
||||
self.assertNotIn("collection", self.render().split("### What changed")[0])
|
||||
|
||||
def test_the_notes_claim_only_what_the_gaps_allow(self):
|
||||
"""v2026.10.10 said a pack holds every file its emulators open, "so a
|
||||
game never stops on a missing file", and that hashes never come
|
||||
"from a forum list". The gap analysis lists what no pack carries."""
|
||||
text = self.render().split("### What changed")[0]
|
||||
self.assertNotIn("every file its emulators", text)
|
||||
self.assertIn("https://abdess.github.io/retrobios/gaps/", text)
|
||||
self.assertEqual(release_notes.refused_words(text), [])
|
||||
|
||||
def test_a_judging_whats_new_is_refused(self):
|
||||
self.assertEqual(
|
||||
release_notes.refused_words(
|
||||
"- Every hash comes from the emulator's source, never from a forum list.\n"
|
||||
"- So a game never stops on a missing file."),
|
||||
["forum", "never stops"])
|
||||
with tempfile.TemporaryDirectory(dir=REPO_ROOT / "tmp") as tmp:
|
||||
whats_new = Path(tmp) / "whats-new.md"
|
||||
whats_new.write_text("- Hashes never from a forum list\n", encoding="utf-8")
|
||||
record = Path(tmp) / "release.json"
|
||||
record.write_text(json.dumps(self.RECORD), encoding="utf-8")
|
||||
argv = ["release_notes.py", "--record", str(record), "--whats-new", str(whats_new),
|
||||
"--platforms-dir", str(REPO_ROOT / "platforms"),
|
||||
"--output", str(Path(tmp) / "notes.md")]
|
||||
with mock.patch.object(sys, "argv", argv), \
|
||||
mock.patch("sys.stderr", new_callable=io.StringIO) as err:
|
||||
self.assertEqual(release_notes.main(), 1)
|
||||
self.assertIn("'forum'", err.getvalue())
|
||||
self.assertFalse((Path(tmp) / "notes.md").exists())
|
||||
|
||||
def test_the_release_process_runs_it(self):
|
||||
page = (REPO_ROOT / "wiki" / "release-process.md").read_text(encoding="utf-8")
|
||||
self.assertIn("scripts/release_notes.py", page)
|
||||
|
||||
@@ -276,7 +276,10 @@ python scripts/generate_site.py
|
||||
|
||||
# 5. Write the notes: install commands, the parts sentence and the pack table
|
||||
# come from release.json, and what changed since the previous tag is the
|
||||
# maintainer's own text in tmp/whats-new.md, appended as written.
|
||||
# maintainer's own text in tmp/whats-new.md, appended as written. The
|
||||
# script refuses a text that judges another project ("forum list") or
|
||||
# promises what the gap analysis contradicts ("never stops"): it says
|
||||
# what changed and how it was checked.
|
||||
python scripts/release_notes.py --whats-new tmp/whats-new.md --output tmp/notes.md
|
||||
|
||||
# Create the release as a DRAFT, upload every asset, and only then publish it.
|
||||
|
||||
Reference in new issue
Block a user