feat: record a release with no genuine copy

Paid Android emulators announce versions that circulate only rebuilt or re-signed. The profile stays on the newest unmodified build, and version_source.no_genuine_copy names the release searched for, so check_freshness stops flagging it until the page announces a later one.
This commit is contained in:
Abdessamad Derraz committed 2026-10-20 04:49:24 +02:00
1 parent 8d295273a5
commit 77389236e6
5 files changed
+49 -7

No files matched your search

+2 -1
View File
@@ -815,7 +815,8 @@
"required": ["url", "pattern"],
"properties": {
"url": {"type": "string", "format": "uri"},
"pattern": {"type": "string", "description": "Regular expression whose first group is the latest version the page announces."}
"pattern": {"type": "string", "description": "Regular expression whose first group is the latest version the page announces."},
"no_genuine_copy": {"type": "string", "description": "An announced version a search found only rebuilt or re-signed copies of. While the page announces it, the profile is not stale. A later version makes it stale again."}
},
"description": "For a project published outside any forge, the page that announces its releases. profile_sync --check-version compares the version read there with core_version."
},
+10 -5
View File
@@ -1110,11 +1110,16 @@ def summarize_profile_sync(report: object) -> list[Finding]:
# Off any forge, the release page is the feed: a version there
# beyond the declared one is a release the profile does not cover.
declared, announced = str(row.get("declared_version") or ""), str(row["page_version"])
findings.append(Finding(
"profiles", name, OK if announced == declared else STALE,
local=declared, remote=announced,
detail="" if announced == declared else "a newer release is announced",
))
if announced == declared:
status, detail = OK, ""
elif announced == str(row.get("no_genuine_copy") or ""):
# Searched for and found only rebuilt: the profile covers the
# newest build that can be read, until the page moves on.
status, detail = OK, "no genuine copy of the announced release"
else:
status, detail = STALE, "a newer release is announced"
findings.append(Finding("profiles", name, status, local=declared,
remote=announced, detail=detail))
continue
if row.get("skipped"):
findings.append(Finding("profiles", name, UNKNOWN, detail=str(row["skipped"])))
+7
View File
@@ -1118,6 +1118,8 @@ class ProfileReport:
# (version_source): the version read there, beside the one declared.
declared_version: str | None = None
page_version: str | None = None
# An announced version searched for and found only rebuilt or re-signed.
no_genuine_copy: str | None = None
# Skips that say the profile cannot be checked as written: a repository
# that no longer answers, no pin to read, a death the forge contradicts.
@@ -2040,6 +2042,9 @@ def format_report(report: ProfileReport, changed_only: bool = False) -> str:
lines.append(
f" version page: declared {report.declared_version or '-'}, "
f"announced {report.page_version or 'unreadable'}"
+ (" (no genuine copy found)"
if report.page_version and report.page_version == report.no_genuine_copy
else "")
)
if report.skipped:
lines.append(f" skipped: {report.skipped}")
@@ -3841,6 +3846,8 @@ def main() -> None:
if args.check_version and profile.get("version_source"):
report.declared_version = str(profile.get("core_version") or "") or None
report.page_version = page_version(profile, args.cache_dir, args.offline)
report.no_genuine_copy = str(
profile["version_source"].get("no_genuine_copy") or "") or None
reports.append(report)
if writes:
try:
+29
View File
@@ -455,6 +455,35 @@ class AReleasePageMakesAProfileStale(unittest.TestCase):
self.assertEqual(found["altirra"], check_freshness.STALE)
self.assertEqual(found["mednafen"], check_freshness.OK)
def test_a_release_with_no_genuine_copy_waits_for_the_next(self):
"""FPse 13.0 exists only as rebuilt copies: the profile stays on 12.1
and flagging it on every run said nothing new. 13.1 would."""
import check_freshness
rows = [
{"name": "fpse", "skipped": "unsupported host: x", "declared_version": "12.1",
"page_version": "13.0", "no_genuine_copy": "13.0"},
{"name": "later", "skipped": "unsupported host: x", "declared_version": "12.1",
"page_version": "13.1", "no_genuine_copy": "13.0"},
]
found = {f.subject: f for f in check_freshness.summarize_profile_sync(rows)}
self.assertEqual(found["fpse"].status, check_freshness.OK)
self.assertIn("no genuine copy", found["fpse"].detail)
self.assertEqual(found["later"].status, check_freshness.STALE)
def test_no_genuine_copy_is_never_the_profiled_version(self):
"""The field names a release the profile could not read."""
import yaml
for path in sorted((REPO_ROOT / "emulators").glob("*.yml")):
text = path.read_text(encoding="utf-8")
if "no_genuine_copy" not in text:
continue
profile = yaml.safe_load(text)
source = profile["version_source"]
with self.subTest(profile=path.stem):
self.assertNotEqual(source["no_genuine_copy"], str(profile["core_version"]))
if __name__ == "__main__":
unittest.main()
+1 -1
View File
@@ -384,7 +384,7 @@ partitions), and `game_count`.
| `adler32_pairs_with`, `adler32_pairs` | the file hashed together with this one and the combinations the code accepts, this file's value first, in table order: Dolphin warns on a DSP ROM pair outside its `known_roms` even when each file passes alone |
| `pin_frozen` | why `source_commit` is held on purpose rather than followed. The profile is then judged against its own revision, like one pinned to a superseded tag |
| `prose_written_at` | the pin a reader confirmed the prose citations against. When the profile's history shows a text living under several pins, profile_sync takes this one as the revision the text describes, so a bump is no longer refused for a citation already reread. It never overrides a history with a single candidate |
| `version_source` | for a project published outside any forge, `{url, pattern}`: the page that announces releases and a regular expression whose first group is the latest version. `profile_sync --check-version` compares it with `core_version`, and `check_freshness --profiles` calls the profile stale when they differ |
| `version_source` | for a project published outside any forge, `{url, pattern}`: the page that announces releases and a regular expression whose first group is the latest version. `profile_sync --check-version` compares it with `core_version`, and `check_freshness --profiles` calls the profile stale when they differ. `no_genuine_copy` names an announced version found only rebuilt or re-signed: the profile stays on the newest unmodified build and is not stale until the page announces a later one |
| `upstream_gone` | why the declared upstream can no longer be reached, when that is settled rather than transient. Records the death instead of leaving the profile failing every pass. profile_sync reports it as declared, and reports the contradiction if the forge answers again |
| `source_mirror` | a repository carrying the same tree, consulted after `source` and `upstream`. What keeps a profile checkable once its own forge stops answering |
| `validation` | checks the code performs: `size`, `crc32`, `md5`, `sha1`, `adler32`, `signature`, `crypto`. Can be a list or dict `{core: [...], upstream: [...]}` for divergent checks |