Georges-Antoine AssiandClaude Opus 5.5 68f71259f7 fix(config): migrate retired filesystem folder keys instead of exiting (#5211)
* fix(config): migrate retired filesystem folder keys instead of exiting

5.2 wrote filesystem.roms_folder and filesystem.firmware_folder into
config.yml on every settings save, so instances that never chose a layout
crash-looped on 5.3.1. Appliance installs (TrueNAS, Unraid, CasaOS) have
no way to edit the file.

Translate the keys at load time into the filesystem.structure templates
that reproduce the layout 5.2 resolved them to, using the same disk check
5.2 used to choose between `<folder>/{platform}` and `{platform}/<folder>`.
A declared structure template still wins. The migrated config is written
back when config.yml is writable; otherwise it applies in memory and logs
the replacement once.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>

* fix(config): refuse folder names a template can't express before migrating

Addresses Greptile review on #5211: a retired folder name containing braces
produced an invalid template after config.yml had already been rewritten.
The migrated templates are now parsed first and startup exits with the
reason, leaving the file untouched. Also trims a test docstring.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>

* fix(config): code-review fixes for the retired folder key migration

Keep an undetectable layout in memory, accept a '.' folder, honour a
differently cased declared key, stop retrying a failed write, and share
the layout detection with check_library_layout.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>

* refactor(config): simplify pass over the retired folder key migration

Build the templates in one pass with a parser per key, reuse get_nested
and the library fixture, skip the layout string on the in-memory path,
and memoize a detected layout across get_config() calls.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>

* test(config): review-polish, drop a docstring that restates the test name

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>

* fix(config): migrate retired folder keys at startup and write config.yml atomically

Loading the config only translates the retired keys in memory now;
startup writes the migration once, before any worker runs, so processes
no longer race to rewrite config.yml.

config.yml is written to a sibling temp file and renamed over the
original, keeping a symlink and the file mode. When the rename fails
(a config.yml bind-mounted on its own), the in-place write puts the
previous content back if it fails, so a full disk no longer empties it.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>

* refactor(config): drop the atomic config write and flatten the folder key migration

The temp-file rename, symlink/mode handling and in-place restore are a
separate concern from migrating the retired keys, so config.yml goes back
to the plain write. The translation validates its two templates directly
instead of through a table of parsers.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <[email protected]>
2026-10-10 10:28:56 -04:00
2026-04-15 19:20:17 -04:00
2024-05-21 19:22:14 -04:00
2024-02-11 16:41:36 +01:00
2024-07-09 13:43:14 +02:00

romm logo

A beautiful, powerful, self-hosted ROM manager and player.

Trendshift hackernews badge
selfh.st badge Discord

Overview

Scan, enrich, browse and play your ROM collection from one beautiful & free self-hosted app. Metadata from 10+ providers, save sync across your devices, and support for over 400 platforms. RomM is a must-have for anyone who plays on emulators.

Browsing a library and playing a game in RomM

Features

Installation

The easiest way to start is with the Quick Start Guide in the docs. If you're having trouble with setup, please review the page for troubleshooting steps.

Prefer a hosted deploy over wiring up the stack yourself?

Deploy on Hostinger
Starting at $6.49/mo · Setup guide

Deployment and infrastructure support for this install is handled by Hostinger. Prices are indicative and may not reflect current offerings. Signups through the link above send a share of the revenue back to us, which helps fund the project.

Official apps

Playnite libraryPlaynite logo Playnite plugin

Effortlessly integrate your retro game collection into Playnite, the open-source game library manager that provides a unified interface for all of your games on PC.

Windows Desktop QR pairing

Install  by @gantoine


Argosy libraryArgosy logo Argosy

Sync your library, download games on demand and track your achievements, from a gamepad-first interface designed for Anbernic, Retroid Pocket, Odin, and similar devices.

Android Handhelds QR pairing Save sync

Download  by @tmgast


Grout multi-selectGrout logo Grout

A lightweight client for your favorite handheld custom firmwares*. Download games, box art and BIOS files wirelessly, and sync your saves automatically as you play.

Linux Handhelds Save sync

Quick start  by @BrandonKowalski

*Supports Allium, Batocera, Knulli, MinUI, muOS, NextUI, Onion, ROCKNIX, Spruce and TrimUI.

Community

Here are some cool projects maintained by members of our community. Please note that our team does not regularly review their source code.

Mobile and TV

Desktop

Handhelds and Steam Deck

Sync

Integrations

Support the project

Consider supporting this project on Open Collective. Funds cover hosting, development, and maintenance, and we pass some along to community projects to nurture a healthy ecosystem of apps.

Open Collective

Our Friends

Here are a few projects that we think you might like:

  • Lutris: Open gaming platform for Linux
  • Cocoon: Controller-first Android frontend for retro handhelds
  • muOS: Custom firmware for Anbernic and other handhelds
  • RetroDECK: Retro gaming on SteamOS and Linux
  • Steam ROM Manager: An app for managing ROMs in Steam
  • Hasheous: Hash lookup service that maps ROMs to game metadata
  • Gaseous: Another ROM manager with web-based emulator
  • Playmatch: Microservice for matching ROM hashes to games
  • EmulatorJS: An embeddable, browser-based emulator
  • PortMaster: Native game ports for Linux handhelds
  • MelonLoader: Universal mod loader for Unity games
  • NextUI: MinUI-based custom firmware for TrimUI handhelds
  • RetroAchievements: Achievements for retro games

Supported By

These companies support us by providing their tools for free:

Greptile Socket
S
Description
A beautiful, powerful, self-hosted ROM manager and player.
Readme AGPL-3.0
466 MiB
Languages
Python 55.8%
Vue 24.5%
TypeScript 18.8%
CSS 0.4%
JavaScript 0.2%
Other 0.3%