fix(setup): a failed update gives the installed Builder its tools back #447
No reviewers
Labels
No labels
area/accessibility
area/audio
area/input
area/install
area/menu
area/renderer
area/saves
area/upscaling
good first issue
gpu/amd
gpu/igpu
gpu/intel
gpu/nvidia
help wanted
kind
bug
kind
chore
kind
docs
kind
feature
kind
performance
kind
question
needs measurements
platform/linux
platform/steam-deck
platform/windows
preview
priority
critical
priority
high
priority
low
status
blocked
status
confirmed
status
duplicate
status
invalid
status
needs-info
status
wontfix
testing wanted
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
MagicBeanDev/Longshot!447
Loading…
Reference in a new issue
No description provided.
Delete branch "jarynclouatre/Longshot:fix/setup-reused-tools-back"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Why
On an ordinary (not portable) Builder install, an update that fails part way (a download or unpack error, or the setup closed) leaves the installed Builder without its tools: it can no longer build, and the next update downloads them all again (llvm-mingw alone is 191 MB).
reuse_partinbuilder/setup/setup.cmoves the folders of the parts that did not change (Python, llvm-mingw, emsdk) out of the installed version intoversions\<tag>.part(if (!g_home.portable) return MoveFileW(from, to) != 0;). Nothing moves them back when the new version is not published, and the next start removes the staging folder with them (rmtree(install)inwork).What changed
builder/setup/setup.c): the move stays (it keeps an update small and quick).note_reused:reuse_partnames each folder in the staging folder'sreused.txtbefore it moves it. A setup stopped between the two leaves a name whose folder is still in the installed version, and nothing moves. When the name cannot be written the part is downloaded instead.restore_reused: moves the folders named inreused.txtback into the installed version (current.txt), only where that version has none, so a part this attempt downloaded and unpacked (perhaps half) never goes into it. Names are checked withlist_name_ok, as the setup list's are.failcalls it once the staging has begun (g_staged), andworkcalls it before it removes an old staging folder, which covers a setup that was closed. After the version is publishedreused.txtis deleted from it.tests/test_setup_tool_merge.py): case 5 runs the realreuse_partandrestore_reusedover a POSIX stand-in: an ordinary update moves an unchanged Python folder over and lists it; (a) after a failure the installed version has it again, bytes the same, and the staging has none; (b) a second attempt moves it over again, no download; (c) a stopped setup: the next start's restore and removal of the staging leave the installed version whole; (d) a folder this attempt unpacked, not listed, stays in the staging; (e) a listed folder whose move failed is not replaced; (f) portable still copies and lists nothing. The stand-in'sCreateFileWgained an append mode andWriteFile; the extractor skips a declaration ahead of its definition.tests/test_portable_setup_transaction.pyextractsnote_reusedwithreuse_partand checks the ordinary move'sreused.txt;tests/test_setup_runtime_paths.pydeclaresg_stagedfor the publication block it extracts.Flags and settings
None.
Measurements
main:
5e072fc8(2026-11-14)this PR: fix/setup-reused-tools-back @
80f44a4fHardware: none used (game-free checks on a Linux x86-64 PC, gcc 15.2, Python 3.14)
Scene: none, the game was not run
Method:
python3 -I -B tests/run_all.py, two runs each, interleaved (main, PR, the other branch, twice). Case 5 also runs against main'ssetup.c, with no-op stand-ins for the two new functions.How to reproduce: the commands above in a checkout of each commit
5e072fc880f44a4ftests/run_all.py(run 1, run 2)test_bake_portability.py,test_menu_keys.py,test_module_ids.py,test_pad_layout.pytests/test_setup_tool_merge.pycase 5after a failed update the installed version has no Pythontest_bake_portability.pyfails here for a missing Python module (zstandard).test_menu_keys.pydoesn't build with g++ andtest_pad_layout.py's fixture lackshost/hold_toggle.h, both on main since #137 (#331 and #338 fix them).test_module_ids.pylooks for a source marker that main no longer has.Testing
Tested: the game-free suite on a Linux PC, as in Measurements.
setup.ccompiles (-fsyntax-only -Wall -Wextra) with llvm-mingw 20261104's x86_64-w64-mingw32-clang with the same 6 warnings as main's. The Windows-only setup checks (test_portable_setup_transaction,test_setup_runtime_paths,test_portable_setup_start,test_setup_runtime,test_portable_setup_paths,test_setup_tar_diagnostics) and the Windows variant oftest_setup_tool_merge's fixture build with that compiler (-Werror).Not tested: those Windows-only checks were built but not run (no Windows PC for them here); the setup itself on Windows: an update of an ordinary install with the network cut after the first parts.
Needs other testers: None.
Screenshots
Nothing on screen.
Risk and rollback
A setup that was closed (not failed) gives the folders back at its next start, before anything is downloaded; the installed Builder started on its own before then still lacks them. A failed move back leaves the folder in the staging, where the next start tries again before removing it (as before this change, it would then be downloaded). Reverting the commit is enough.
Issues
None filed.
Checklist
For everyone
type(scope): description).main.python -I -B tests/run_all.pyrun and passing (any failure that also fails onmainis named above).third_party/untouched (a new folder with aPROVENANCE.mdinstead).If applicable
mainand passing here.tests/that reads changed source updated in this PR, not weakened.WIP: fix(setup): a failed update gives the installed Builder its tools backto fix(setup): a failed update gives the installed Builder its tools backView command line instructions
Checkout
From your project repository, check out a new branch and test the changes.