Skip to content

Use the XDG base directories - #113

Open
Quintasan wants to merge 1 commit into
TannerMidd:mainfrom
Quintasan:xdg-directories
Open

Quintasan wants to merge 1 commit into
TannerMidd:mainfrom
Quintasan:xdg-directories

Conversation

@Quintasan

Copy link
Copy Markdown
Contributor

Pi Pocket keeps everything in one folder, ~/.pi-pocket: the database, people and their tokens, uploads, worktrees, extension drop-ins, the tunnel's log, and the browser's profile. Nothing there follows the XDG base directory spec, and it mixes secrets with caches.

This splits them by kind, the way the spec asks:

Kind Default Holds
config ~/.config/pi-pocket config.json (people, roles, tokens, settings), launcher.json
data ~/.local/share/pi-pocket pocket.sqlite and its lock, push.json, uploads/, worktrees/, repos/, gallery/, themes/, extensions/
state ~/.local/state/pi-pocket the Cloudflare tunnel's log
cache ~/.cache/pi-pocket the downloaded cloudflared, the built-in browser's profile

XDG_*_HOME moves them. PI_POCKET_CONFIG_DIR, PI_POCKET_DATA_DIR, PI_POCKET_STATE_DIR, and PI_POCKET_CACHE_DIR name each one itself, so the --data option and PI_POCKET_DIR are gone (they named one folder, which is no longer the shape). The launcher passes the four resolved folders to the server, so the two always agree.

Migration. src/server/dirs.ts moves an older ~/.pi-pocket into the four, once, entry by entry:

  • it runs only where the destination has nothing, so a migration cut off midway finishes on the next start;
  • a file it does not recognise is left where it is, with a line naming it;
  • a database already in the data folder is kept and named, instead of being passed over in silence while the app runs on it;
  • a Pi Pocket still running on the old folder (a live harness.lock) stops the migration with a message, rather than moving a database out from under it;
  • a cross-filesystem move copies to a .partial name and renames it into place, so a copy cut short is never mistaken for a finished one;
  • the legacy folder is removed only when it is empty.

Compatibility. host.dataDir keeps meaning the data folder, and nothing in types/pocket.d.ts changes, so no module or reference page gets a new Since line. The lock stays in the data folder: it guards that database and its message says which folder is taken, so a second instance with its own data folder still runs. The NixOS module pins all four folders to dataDir, so an existing service deployment keeps its files exactly where they are rather than starting on empty folders.

Tested. npm run format, npm run check, npm run lint, and npm test: 356 tests, 315 pass, 8 fail — the same 8 test/pi-sessions.test.ts tests that fail on main here before any change (this machine's Pi session files), plus model-refresh intermittently. New tests in test/dirs.test.ts cover the XDG precedence (including relative, empty, and PI_POCKET_*_DIR overrides), the folder modes, a full legacy migration (database with -wal/-shm, extensions, worktrees, repos, tunnel log, cloudflared, browser profile), idempotency, no overwriting, the database-already-there case, and the still-running case. test/qol.test.ts now checks a guest cannot read config.json, launcher.json, pocket.sqlite, push.json, the tunnel log, the browser's cookies, or what a migration left in the old folder. Also ran a throwaway-HOME end-to-end check: a fake legacy folder migrates into the four, an unknown file stays behind with a line, and a second run does nothing.

One known effect: documents written before the upgrade name files by their old absolute path — an older message's attachments, an isolated session's worktree, a PiP clone in a session's folder. Those paths move with everything else, and the migration log says so, but the old messages and sessions then point at the old folder. Keeping ~/.pi-pocket (or symlinking uploads/, worktrees/, and repos/ back to the data folder) keeps them working; rewriting the stored paths would be a separate change. Say if you would like that in this PR instead.

Also updated the docs the paths appear in (README.md, AGENTS.md, SECURITY.md, docs/**, site/**) and the NixOS module and its tests.

Pi Pocket kept everything in one folder, `~/.pi-pocket`: the database, people
and their tokens, uploads, worktrees, extension drop-ins, the tunnel's log, and
the browser's profile. That is not where any of them belong, and it put
secrets beside caches.

Each part now goes where the XDG base directory spec puts it: settings in
`~/.config/pi-pocket`, the database and what sessions write in
`~/.local/share/pi-pocket`, the tunnel's log in `~/.local/state/pi-pocket`, and
the profile and downloaded cloudflared in `~/.cache/pi-pocket`. `XDG_*_HOME`
moves them, and `PI_POCKET_CONFIG_DIR`, `PI_POCKET_DATA_DIR`,
`PI_POCKET_STATE_DIR`, and `PI_POCKET_CACHE_DIR` name each one itself: the
`--data` option and `PI_POCKET_DIR`, which named one folder, are gone.

An older `~/.pi-pocket` moves into the new folders once (`dirs.ts`), entry by
entry, and only where the destination has nothing: a migration cut off midway
finishes on the next start, an unknown file stays where it is with a line
saying so, a database already in the data folder is kept and named rather than
silently passed over, and a Pi Pocket still running on the old folder stops the
migration with a message instead of moving a live database. Files that older
messages and isolated sessions name by their old absolute path are reported
too, as they now live under the data folder.

`host.dataDir` keeps meaning the data folder and no interface in
`types/pocket.d.ts` changes; the lock stays in the data folder, since it guards
that database and says which folder is taken. The NixOS module sets all four
folders to `dataDir`, so an existing deployment keeps its files where they are.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant