PATCH-04: backup <path>.bak abans de reescriure config/presets per fallada
Helper `backupFile(path)` que copia el YAML a `<path>.bak` si existeix. Es crida a `loadFromFile` (versió mismatch i catch) i a `loadPresetsFromFile<T>` (manca `presets:`, llista buida, catch). La primera execució no genera .bak. Cada reescriptura forçada registra el motiu per stderr (INCONS-02 migrarà a std::cout). Prova manual: config.yaml amb contingut \"===broken===\" genera config.yaml.bak amb el contingut previ i un nou config.yaml amb defaults.
This commit is contained in:
1 parent
505c20dabc
commit
db2e5d66e0
2 files changed
+31
-4
No files matched your search
+2
-2
@@ -21,7 +21,7 @@ Els IDs es mantenen estables una vegada assignats. Cada entrada apunta al fitxer
|
||||
| HC-03 | Geometria del mapa cablejada a `map.hpp` (bloqueja "pirámide a pirámide") | DONE |
|
||||
| COUP-01 | `core/` inclou `game/ui/notification_presets.hpp` (dependència invertida) | DONE |
|
||||
| DUP-01 | PostFX i CrtPi són dos pipelines duplicats a `options.cpp` | DONE |
|
||||
| PATCH-04 | Reescriure silenciosament `config.yaml` al fallar parseig o versió | PENDING |
|
||||
| PATCH-04 | Reescriure silenciosament `config.yaml` al fallar parseig o versió | DONE |
|
||||
| HC-01 | `SPEED_PX_PER_S`, caixa de col·lisió i rutes d'assets cablejades | PENDING |
|
||||
|
||||
---
|
||||
@@ -56,7 +56,7 @@ Els IDs es mantenen estables una vegada assignats. Cada entrada apunta al fitxer
|
||||
| PATCH-01 | `player.cpp:66-77` | Col·lisió per eix fent `AnimatedSprite::update` + revertir + reaplicar | Importante | PENDING | `tryMove(dx, dy, collisionFn)` a la classe base |
|
||||
| PATCH-02 | `player.cpp:13-15` | Comentari tipus TODO ("si més endavant volem sprint...") | Menor | PENDING | Treure o convertir en feature amb issue |
|
||||
| PATCH-03 | `map.cpp:13-15` | `overlapStrict` custom perquè SDL3 considera el toc com intersecció | Menor | PENDING | Si s'usa més, mourea `utils/` |
|
||||
| PATCH-04 | `options.cpp:361-363,371-375,475-480,528-533` | Reescriure silenciosament `config.yaml` al fallar parseig o canviar versió | Crítico | PENDING | `.bak` + log abans de sobreescriure |
|
||||
| PATCH-04 | `options.cpp:361-363,371-375,475-480,528-533` | Reescriure silenciosament `config.yaml` al fallar parseig o canviar versió | Crítico | DONE | Helper `backupFile()` que copia a `<path>.bak` si existeix. Cridat abans de cada reescriptura forçada (versió mismatch + catch a `loadFromFile`, `presets:` absent/invàlid/buit + catch a `loadPresetsFromFile`). Primera execució no genera `.bak`. Missatge explícit per motiu de reescriptura |
|
||||
| PATCH-05 | `game_scene.cpp:51` | `if (Audio::get() != nullptr)` com a defensa sobre un singleton Meyers | Menor | PENDING | Assumir invariant, treure |
|
||||
| PATCH-06 | `game_scene.cpp:78-91` | Ordenació per `getFeetY()` amb 1 jugador i sense sarcs-sprite: cerimonial | Menor | PENDING | Comentar "reactivar quan hi haja sarcs-sprite" o treure |
|
||||
| PATCH-07 | `map.hpp:64` + `map.cpp:19` | `Map` declara ctor però tots els mètodes són `static` (transició a mitges) | Importante | PENDING | Decidir: namespace o instanciar |
|
||||
|
||||
+29
-2
@@ -76,6 +76,20 @@ namespace {
|
||||
return file.good();
|
||||
}
|
||||
|
||||
// Còpia `<path>` a `<path>.bak` per protegir ediciones manuals de
|
||||
// l'usuari quan estem a punt de reescriure el fitxer amb defaults per
|
||||
// error de parseig o canvi de versió. Si el fitxer no existeix (primera
|
||||
// execució) o no es pot obrir, no fa res: no hi ha res a salvar.
|
||||
void backupFile(const std::string& path) {
|
||||
if (path.empty()) { return; }
|
||||
std::ifstream src(path, std::ios::binary);
|
||||
if (!src) { return; }
|
||||
std::ofstream dst(path + ".bak", std::ios::binary);
|
||||
if (!dst) { return; }
|
||||
dst << src.rdbuf();
|
||||
std::cerr << "Options: còpia de seguretat a " << path << ".bak\n";
|
||||
}
|
||||
|
||||
void parseWindow(const fkyaml::node& yaml) {
|
||||
if (!yaml.contains("window")) { return; }
|
||||
const auto& node = yaml["window"];
|
||||
@@ -351,12 +365,15 @@ namespace {
|
||||
|
||||
const std::string CONTENT = readFileOrEmpty(path);
|
||||
if (CONTENT.empty()) {
|
||||
// Primera execució (no existia o era buit): no cal backup.
|
||||
presets = defaults_fn();
|
||||
return save_fn();
|
||||
}
|
||||
try {
|
||||
auto yaml = fkyaml::node::deserialize(CONTENT);
|
||||
if (!yaml.contains("presets") || !yaml["presets"].is_sequence()) {
|
||||
std::cerr << "Options: " << kind_label << " manca `presets:`; reescrivint amb defaults.\n";
|
||||
backupFile(path);
|
||||
presets = defaults_fn();
|
||||
return save_fn();
|
||||
}
|
||||
@@ -367,6 +384,8 @@ namespace {
|
||||
presets.push_back(preset);
|
||||
}
|
||||
if (presets.empty()) {
|
||||
std::cerr << "Options: " << kind_label << " sense presets; reescrivint amb defaults.\n";
|
||||
backupFile(path);
|
||||
presets = defaults_fn();
|
||||
return save_fn();
|
||||
}
|
||||
@@ -374,6 +393,7 @@ namespace {
|
||||
} catch (const std::exception& e) {
|
||||
std::cerr << "Options: error parsejant " << kind_label << ": " << e.what() << '\n';
|
||||
std::cerr << "Options: reescrivint el fitxer amb presets per defecte.\n";
|
||||
backupFile(path);
|
||||
presets = defaults_fn();
|
||||
return save_fn();
|
||||
}
|
||||
@@ -426,8 +446,14 @@ namespace Options {
|
||||
file_version = yaml["version"].get_value<std::string>();
|
||||
}
|
||||
// Sense migració per ara: si la versió no coincideix, reescrivim
|
||||
// amb els defaults de la versió nova.
|
||||
if (file_version != Texts::VERSION) { return saveToFile(); }
|
||||
// amb els defaults de la versió nova. El fitxer original queda
|
||||
// a `<path>.bak` per si l'usuari volia preservar tuning manual.
|
||||
if (file_version != Texts::VERSION) {
|
||||
std::cerr << "Options: config.yaml versió \"" << file_version
|
||||
<< "\" != \"" << Texts::VERSION << "\"; reescrivint amb defaults.\n";
|
||||
backupFile(config_file_path);
|
||||
return saveToFile();
|
||||
}
|
||||
config_version = file_version;
|
||||
|
||||
if (yaml.contains("locale")) { Options::locale = yaml["locale"].get_value<std::string>(); }
|
||||
@@ -438,6 +464,7 @@ namespace Options {
|
||||
} catch (const std::exception& e) {
|
||||
std::cerr << "Options: error parsejant config.yaml: " << e.what() << '\n';
|
||||
std::cerr << "Options: reescrivint el fitxer amb defaults.\n";
|
||||
backupFile(config_file_path);
|
||||
return saveToFile();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user