feat(framework): convencion local_files/ — separacion distribuible vs estado
Toda app C++ basada en fn::run_app coloca sus archivos escribibles
bajo <exe_dir>/local_files/. Los distribuibles (.exe, dlls, ttfs,
enrichers/, runtime/) siguen junto al .exe. Esto deja la carpeta
distribuible limpia para zippear y separa con claridad lo que
viaja con la app de lo que el PC genera.
API publica en fn:: (cpp/framework/app_base.h):
- exe_dir() directorio del ejecutable
- local_dir() <exe_dir>/local_files/, creado on-demand
- local_path(name) <local_dir>/<name>
- migrate_to_local_files(...) mueve archivos viejos desde cwd/exe_dir
Cambios:
- run_app configura io.IniFilename = local_path("imgui.ini") y
llama migrate_to_local_files(["imgui.ini","app_settings.ini"])
antes de settings_load(). Migracion idempotente para PCs con
instalacion previa.
- app_settings.cpp usa local_path("app_settings.ini") en lugar de
hardcoded "app_settings.ini" relativo al cwd.
- cpp_apps.md §7 documenta la convencion como obligatoria. Las
apps deben usar fn::local_path() para cualquier archivo
escribible nuevo.
Beneficios:
- zip distribuible no se "ensucia" con .ini/.db generados al usar.
- reset trivial: borrar local_files/.
- backup/sync per-PC: solo local_files/ es propio del PC.
- elimina la mezcla de paths Linux/Windows que generaba bugs como
"projects\\default\\operations.db" en builds cross-platform.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -120,7 +120,52 @@ Cada app C++ es su propio repo en `dataforge/<name>` con branch `master`. Esto s
|
||||
- TBD obligatorio mientras se desarrolla la app: ver `apps_tbd.md`. Trabajar en `issue/<NNNN>-<slug>` o `quick/<slug>`, mergear a `master` con `--no-ff`.
|
||||
- Sync entre PCs y push/pull se gestionan con `/full-git-push` y `/full-git-pull`.
|
||||
|
||||
### 7. Convenciones de runtime
|
||||
### 7. Convencion `local_files/` — separacion de distribuible vs estado local
|
||||
|
||||
**OBLIGATORIO**: TODA app coloca sus archivos escribibles bajo
|
||||
`<exe_dir>/local_files/`. Los archivos distribuibles (`.exe`, `.dll`,
|
||||
`.ttf`, `enrichers/`, `runtime/`) viven directos en `<exe_dir>/`.
|
||||
|
||||
```
|
||||
<exe_dir>/
|
||||
├── <app>.exe
|
||||
├── duckdb.dll, *.ttf, runtime/, enrichers/ ← read-only, ships con el zip
|
||||
└── local_files/ ← writable, per-PC
|
||||
├── imgui.ini ← gestionado por fn::run_app
|
||||
├── app_settings.ini ← gestionado por fn_ui::settings_*
|
||||
└── <lo que la app escriba> ← usar fn::local_path("nombre")
|
||||
```
|
||||
|
||||
`fn::run_app` lo gestiona automaticamente para `imgui.ini` y
|
||||
`app_settings.ini` y migra desde `<exe_dir>/` o `cwd` si vienen de
|
||||
una version previa.
|
||||
|
||||
Apps que escriban archivos extra (DBs, caches, proyectos del
|
||||
usuario) **DEBEN** usar `fn::local_path("nombre")` al construir
|
||||
sus paths. Ejemplo:
|
||||
|
||||
```cpp
|
||||
// MAL
|
||||
sqlite3_open("graph_explorer.db", &db);
|
||||
fopen("graph_explorer.ini", "r");
|
||||
|
||||
// BIEN
|
||||
sqlite3_open(fn::local_path("graph_explorer.db"), &db);
|
||||
fopen(fn::local_path("graph_explorer.ini"), "r");
|
||||
```
|
||||
|
||||
API en `cpp/framework/app_base.h`:
|
||||
- `fn::exe_dir()` — directorio del ejecutable.
|
||||
- `fn::local_dir()` — `<exe_dir>/local_files/`, creado on-demand.
|
||||
- `fn::local_path(name)` — `<local_dir>/<name>`.
|
||||
- `fn::migrate_to_local_files(names, n)` — mueve archivos viejos.
|
||||
|
||||
Beneficios:
|
||||
- Carpeta del .exe limpia para distribuir (zip portable).
|
||||
- Reset trivial (basta borrar `local_files/`).
|
||||
- Separacion clara para backup/sync (solo `local_files/` es propio del PC).
|
||||
|
||||
### 8. Convenciones de runtime
|
||||
|
||||
Cumplir el checklist completo de `cpp/PATTERNS.md`. Resumen de lo que NUNCA debe aparecer en una app:
|
||||
|
||||
@@ -134,6 +179,7 @@ Cumplir el checklist completo de `cpp/PATTERNS.md`. Resumen de lo que NUNCA debe
|
||||
| About hardcoded en un panel | `cfg.about = {...}` |
|
||||
| `gl*` directo sin loader | `cfg.init_gl_loader = true` |
|
||||
| Tabla SQLite en la raiz del repo | `<app_dir>/<app>.db` (operations.db es solo para entities/relations/executions) |
|
||||
| `fopen("foo.ini", ...)` con path relativo | `fopen(fn::local_path("foo.ini"), ...)` (ver §7) |
|
||||
|
||||
### 8. Tests visuales (recomendado, no obligatorio)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user