mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-10-20 10:23:16 -05:00
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:
1 parent
8d295273a5
commit
77389236e6
5 files changed
+49
-7
No files matched your search
@@ -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."
|
||||
},
|
||||
|
||||
@@ -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"])))
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
@@ -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 |
|
||||
|
||||
Reference in new issue
Block a user