fix: keep bottle settings loadable across versions and crashes#102
Merged
Conversation
- Write Metadata.plist atomically so an interrupted save can't truncate it - Decode unknown GraphicsBackend values leniently (.recommended for the bottle config, nil for program overrides and game-DB variants) so settings written by a newer Whisky still load — forward-compat groundwork for new backends
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
Address review on the settings-robustness change: - Generalize decodeGraphicsBackendIfPresent into a reusable decodeLenientIfPresent<T: RawRepresentable where RawValue == String>, so the upcoming DXMT backend case needs no new plumbing, and apply it to the other string-backed enums in the same decode paths (performancePreset, resolutionPreset) — they had the same brick-the-whole-file failure mode. - Log the unknown-value and malformed-type fallbacks via Logger.wineKit so a corrupted or foreign setting is diagnosable instead of silently reset. - Narrow the doc comment: keyed-Codable enums (EnhancedSync, DXVKHUD) are not covered and still decode strictly. - Add tests: malformed (wrong-typed) backend value, persist/reload round-trip after fallback, and performancePreset leniency; guard the substitution tests against silently becoming no-ops if the encoding shape changes. - CHANGELOG: overrides/game-DB entries fall back to inheriting the bottle's choice (not .recommended); atomic write covers crash, not power loss.
6c2f52e to
075ccc7
Compare
…t files - Apply the lenient enum decode to every persisted string-backed enum (wine, launcher, audio, cleanup, display, and performance presets), not only the graphics backend, so settings written by a newer Whisky still load instead of resetting the whole bottle to defaults - Quarantine an unreadable Metadata.plist (move it aside, preserved for diagnosis) before writing defaults, instead of silently overwriting it - Classify the decode-failure logs (corruption at .error, forward-compat at .warning) with the coding path and non-redacted type and error - Add regression tests for the bottle-level presets and the quarantine path - Remove a stray exported signing key and gitignore key and cert export patterns
075ccc7 to
82813f2
Compare
…program settings A failed wine-version stamp rewrite after a successful decode no longer propagates as a load failure, which moved a perfectly valid Metadata.plist into quarantine and reset the bottle to defaults. The stamp now retries on the next load instead. Per-program settings get the same protections bottle settings already had: atomic writes, and quarantining an undecodable file before defaults replace it. Quarantine filenames now carry a random suffix so two recoveries in the same second cannot collide and drop the second file. Decode-failure and unknown-enum log lines are now marked public (they carry fixed enum tokens and bottle paths, not personal data) so release logs stay diagnosable. Tests cover the file-version-mismatch quarantine path, stamp-write-failure resilience, and unknown-value fallback for the audio, cleanup, and launcher config groups.
3182024 to
73b7509
Compare
# Conflicts: # .gitignore # CHANGELOG.md
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.
Summary
BottleSettings.encode(to:)used a baredata.write(to:), so a crash or power loss mid-save could leave a truncatedMetadata.plistand wipe the bottle's configuration. Now writes with.atomic.GraphicsBackenddecode: the doc comment onBottleGraphicsConfigpromised unknown values decode gracefully to.recommended, butdecodeIfPresent(GraphicsBackend.self)actually throws on an unknown raw value — failing the entire bottle settings load. A newdecodeGraphicsBackendIfPresenthelper decodes the raw string and falls back (.recommendedfor the bottle config,nilfor program overrides and game-DB variants). This is forward-compat groundwork: a bottle written by a future Whisky with a new backend still opens on this build.Verification
BottleSettingspath,GameConfigVariantSettings,ProgramOverrides) — all reproduced thedataCorruptedfailure before the fix.