fix(update): a folder newer than the latest release is not offered the older one #2519

Merged
NotRexed merged 1 commit from fix/update-no-downgrade into main 2026-11-11 22:22:24 +00:00
NotRexed commented 2026-11-11 21:44:29 +00:00 (Migrated from github.com)

The bug. The v2.2.0 test build (built from main, labelled v2.2.0 while v2.1.0 is the latest release) opened with the update prompt: "A new version of Hookshot is out: v2.1.0 (this game is v2.2.0). Update now?". Update would have built 2.1.0 over the test folder. The log said it plainly: update: this folder is v2.2.0, the latest release is v2.1.0.

hos_update_check only kept a release candidate from being offered an older version; a release was offered any tag that differed from its own.

The fix (host/hos_update.c, Windows and Linux): a release or release candidate newer than the latest release is offered nothing. Nightlies are unchanged. The existing release-candidate guard stays as it was.

Tests: tests/test_update_tracks.py checks the new guard is in both copies; the version order it relies on (newer_version) is already compiled and checked there. 6 tests pass (clang).

🤖 Generated with Claude Code

**The bug.** The v2.2.0 test build (built from main, labelled v2.2.0 while v2.1.0 is the latest release) opened with the update prompt: "A new version of Hookshot is out: v2.1.0 (this game is v2.2.0). Update now?". Update would have built 2.1.0 over the test folder. The log said it plainly: `update: this folder is v2.2.0, the latest release is v2.1.0`. `hos_update_check` only kept a release candidate from being offered an older version; a release was offered any tag that differed from its own. **The fix** (`host/hos_update.c`, Windows and Linux): a release or release candidate newer than the latest release is offered nothing. Nightlies are unchanged. The existing release-candidate guard stays as it was. **Tests:** `tests/test_update_tracks.py` checks the new guard is in both copies; the version order it relies on (`newer_version`) is already compiled and checked there. 6 tests pass (clang). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
hckrman101 (Migrated from github.com) approved these changes 2026-11-11 22:17:37 +00:00
hckrman101 (Migrated from github.com) left a comment

Looks good. The guard is right: newer_version(have, tag) is only true when both parse as vX.Y.Z[-rc.N] and the folder is strictly newer, so v2.2.0 against a latest of v2.1.0 returns before any prompt, and an equal or older folder, or a version that does not parse, is offered exactly as before. Nightlies are skipped by !nightly_version(have), and both the Windows and Linux copies sit right after the existing equal/skipped/rc checks, before anything is shown or the builder is looked up.

Nits, none blocking:

  • For a release candidate the new line is redundant, since the line above already returns when the tag is not newer than the folder. Only the release case is new, so the comment could say that.
  • The test counts the guard text in the source (like the existing rc check) rather than running it; fine since newer_version is already compiled and tested there.
  • A folder version that does not parse (say a -dirty release) is still offered whatever the latest is. Same as before, so no regression.

Overlap with #2430: that PR also edits host/hos_update.c (builder shape check, env stripping, skip-file writes) and tests/test_update_tracks.py, but in other hunks. On the Windows side it starts at the has_builder lines, a few lines below this guard. On Linux it adds struct stat bst; after the snprintf(path, ...) line, one line below this guard. So I expect a clean merge in either order, though I only compared the patches and did not try a merge. Semantically they are independent: this decides whether to offer, #2430 how the offer runs.

CI is green. Nobody else has reviewed or commented so far.

Looks good. The guard is right: `newer_version(have, tag)` is only true when both parse as vX.Y.Z[-rc.N] and the folder is strictly newer, so v2.2.0 against a latest of v2.1.0 returns before any prompt, and an equal or older folder, or a version that does not parse, is offered exactly as before. Nightlies are skipped by `!nightly_version(have)`, and both the Windows and Linux copies sit right after the existing equal/skipped/rc checks, before anything is shown or the builder is looked up. Nits, none blocking: - For a release candidate the new line is redundant, since the line above already returns when the tag is not newer than the folder. Only the release case is new, so the comment could say that. - The test counts the guard text in the source (like the existing rc check) rather than running it; fine since `newer_version` is already compiled and tested there. - A folder version that does not parse (say a `-dirty` release) is still offered whatever the latest is. Same as before, so no regression. Overlap with #2430: that PR also edits `host/hos_update.c` (builder shape check, env stripping, skip-file writes) and `tests/test_update_tracks.py`, but in other hunks. On the Windows side it starts at the `has_builder` lines, a few lines below this guard. On Linux it adds `struct stat bst;` after the `snprintf(path, ...)` line, one line below this guard. So I expect a clean merge in either order, though I only compared the patches and did not try a merge. Semantically they are independent: this decides whether to offer, #2430 how the offer runs. CI is green. Nobody else has reviewed or commented so far.
Commenting is not possible because the repository is archived.
No description provided.