feat(update): cache fetched release notes and strict-match patch notes version

This commit is contained in:
1jamie
2026-08-16 15:31:19 -05:00
parent 46f73b7bb3
commit e9a4a592a4
3 changed files with 82 additions and 7 deletions
+42 -7
View File
@@ -16,6 +16,10 @@ PatchNotes.FILES = {
"assets/PATCH_NOTES.md",
}
PatchNotes.CACHE_FILES = {
"updates/notes_cache.json",
}
PatchNotes.REPO_FILES = {
"mobile/ios/app-repo.json",
}
@@ -48,6 +52,29 @@ local function readPath(path)
return nonempty(text) and text or nil
end
function PatchNotes.fromCache(engine)
for _, path in ipairs(PatchNotes.CACHE_FILES) do
local text = readPath(path)
if text then
local ok, doc = pcall(Json.decode, text)
if ok and type(doc) == "table" then
if engine and engine ~= "0.0.0-dev" then
if doc[engine] and nonempty(doc[engine]) then
return doc[engine], engine
end
else
for ver, notes in pairs(doc) do
if nonempty(notes) then
return notes, ver
end
end
end
end
end
end
return nil, nil
end
function PatchNotes.fromFile()
for _, path in ipairs(PatchNotes.FILES) do
local text = readPath(path)
@@ -88,6 +115,7 @@ function PatchNotes.fromRepo(engine)
return row.notes, row.version
end
end
return nil, nil
end
return list[1].notes, list[1].version
end
@@ -96,17 +124,24 @@ function PatchNotes.fromRepo(engine)
end
function PatchNotes.body(Check)
local notes, ver = PatchNotes.fromCheck(Check)
if notes then return notes, ver end
notes = PatchNotes.fromFile()
if notes then return notes, ver end
local Version = require("src.core.Version")
local engine = (Version and Version.engine) or "?"
local notes, ver = PatchNotes.fromCheck(Check)
if notes and (engine == "0.0.0-dev" or ver == engine or ver == nil) then
return notes, ver or engine
end
notes, ver = PatchNotes.fromCache(engine)
if notes then return notes, ver end
notes = PatchNotes.fromFile()
if notes then return notes, engine end
notes, ver = PatchNotes.fromRepo(engine)
if notes then return notes, ver end
return "No patch notes loaded yet for gen1recomp v" .. engine .. ".\n\n"
.. "They appear here after the launcher checks GitHub for the latest "
.. "release.", engine
return "Unable to fetch patch notes.", engine
end
return PatchNotes
+25
View File
@@ -151,6 +151,28 @@ local function gatePasses(rel)
return not (info.minShell and info.minShell > shell)
end
local function cacheNotes(ver, notes)
if not (ver and type(notes) == "string" and notes ~= "" and Json) then return end
if not (love and love.filesystem) then return end
pcall(function()
love.filesystem.createDirectory("updates")
local cachePath = "updates/notes_cache.json"
local existing = {}
if love.filesystem.getInfo and love.filesystem.getInfo(cachePath) then
local text = love.filesystem.read(cachePath)
if text then
local ok, doc = pcall(Json.decode, text)
if ok and type(doc) == "table" then existing = doc end
end
end
existing[ver] = notes
local ok, encoded = pcall(Json.encode, existing)
if ok and encoded then
love.filesystem.write(cachePath, encoded)
end
end)
end
-- ---------------------------------------------------------------------------
-- check
-- ---------------------------------------------------------------------------
@@ -177,6 +199,9 @@ local function doCheck()
return
end
pending = rel
if rel.version and type(rel.notes) == "string" and rel.notes ~= "" then
cacheNotes(rel.version, rel.notes)
end
-- Unstamped dev build: the working tree always looks "newer", so never
-- pester the developer with an update (contract item, Check design).
+15
View File
@@ -68,6 +68,12 @@ do
"stashed notes name a release version")
end
do
local notes, ver = PatchNotes.fromRepo("999.999.999")
eq(notes, nil, "fromRepo returns nil when a specific engine version is missing")
eq(ver, nil, "fromRepo version is nil when missing")
end
do
local f = assert(io.open("mobile/ios/app-repo.json", "rb"))
local list = PatchNotes.parseRepo(f:read("*a"))
@@ -78,6 +84,15 @@ do
eq(notes, list[2].notes, "fromRepo returns that version's notes")
end
do
local oldVersion = package.loaded["src.core.Version"]
package.loaded["src.core.Version"] = { engine = "999.999.999" }
local body, ver = PatchNotes.body(nil)
eq(body, "Unable to fetch patch notes.", "returns Unable to fetch patch notes when version is uncached and unlisted")
eq(ver, "999.999.999", "returns the requested engine version")
package.loaded["src.core.Version"] = oldVersion
end
imp._appPatchNotes = true
local modal = drawAndCapture(imp)
check(modal:find("Patch notes", 1, true) ~= nil, "the modal titles itself")