fix: harden bottle registry and surface silent bottle-creation failures - #136
Open
frankea wants to merge 4 commits into
Open
fix: harden bottle registry and surface silent bottle-creation failures#136frankea wants to merge 4 commits into
frankea wants to merge 4 commits into
Conversation
- An unreadable bottle registry is now moved aside (with an alert saying where) and paths are recovered from the fallback format when possible, instead of being overwritten with an empty list on startup - Bottle creation verifies the registry write on disk and raises the previously never-thrown persistenceSaveFailed error, so a failed save shows the failure alert instead of the bottle vanishing on next launch - Creating a bottle without the WhiskyWine runtime installed fails fast with an actionable "runtime missing" error and a Run Setup button - The Winetricks Terminal flow shows an error when the bundled winetricks resources are missing instead of silently doing nothing Refs #61, #134 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014NkZVxUeRT7ejcP7mppS2D
SwiftLint flagged runCommandInternal (function_body_length 59/50) and the ContentView struct (type_body_length 272/250) after the new error alerts. Extract the repair-failed and missing-resources alerts into helpers (the former deduplicates an identical inline alert in repairPrefixAndRetry) and move ContentView's sidebar/detail/filteredBottles into a same-file extension. No behavior change. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014NkZVxUeRT7ejcP7mppS2D
SwiftFormat's blankLinesAtEndOfScope flagged the leftover blank line from moving the subview builders into an extension. Verified clean with the same SwiftFormat 0.58.7 Linux binary and config CI uses. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014NkZVxUeRT7ejcP7mppS2D
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
Codecov's patch gate requires 60% coverage of the WhiskyKit diff; the new BottleData logic had none. Make the registry location injectable (internal init(entriesFile:), following the WhiskyWineInstaller pattern of parameterizing paths for testability) and add BottleDataTests covering first-run creation, register-and-reload round trips, idempotent registration, corrupt-registry backup, and salvage of the paths-only fallback format. Production behavior is unchanged - init() still uses the standard registry location. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014NkZVxUeRT7ejcP7mppS2D
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to the new reports on #61 and #134 (both from the same user on 2026-07-25). Reviewing the remaining failure paths turned up four gaps that can still make bottles disappear silently or leave the user with no feedback; this PR closes all four.
Changes
1. An unreadable bottle registry is no longer wiped (Refs #61)
BottleData.initused to respond to a failed decode ofBottleVM.plistby immediately re-encoding an empty registry over it — every registered bottle vanished from the sidebar with no error and no way back. Now:encodeFallback(), which the primary decoder could never read back) is salvaged before the file is treated as corrupt.BottleVM.corrupt-<timestamp>.plistinstead of being overwritten, and an alert on launch tells the user where it went and that their bottle folders were not deleted.2. Registry save failures now surface (Refs #61)
BottleCreationError.persistenceSaveFailedexisted but was never thrown —BottleData.encode()'s failure result was silently discarded, so a bottle that couldn't be saved looked created and then vanished on the next launch. Bottle creation now goes throughregisterBottlePath(_:), which verifies the entries file on disk actually contains the new path and throws into the existing failure alert (with copyable diagnostics) when it doesn't.3. Missing Wine runtime fails fast with a way out (Refs #61)
Creating a bottle without WhiskyWine installed (failed/skipped first-run download) previously died mid-creation with a low-level file-not-found error. The preflight now checks
isWhiskyWineInstalled()and throws a dedicatedruntimeMissingerror, and the failure alert gains a Run Setup… button that opens the setup sheet directly.4. Winetricks no longer silently does nothing (Refs #134)
Winetricks.runCommandreturned without any feedback when the bundled resources couldn't be located. It now shows a critical alert with reinstall guidance, matching the headless install path's behavior.Also adds the six new localized strings (English source; Crowdin sync picks them up) and a
[Unreleased]changelog entry.Testing
Localizable.xcstringsvalidated as JSON; new keys inserted in Xcode's sorted format..swiftlint.yml.🤖 Generated with Claude Code
https://claude.ai/code/session_014NkZVxUeRT7ejcP7mppS2D
Generated by Claude Code