Files
dotfiles/.config/dot/.claude/tasks/000c-folders-fixed-target-mapping.md
alexion 1fd8e7e773 dotcli: add dot setup folders (XDG short-name migration)
Adds a dot setup subcommand family (idempotent, re-runnable machine-setup
tasks) with a folders task that brings the 8 standard XDG user
directories under a fixed short-name convention (Desktop -> .desktop,
Documents -> doc, Downloads -> dwn, Music -> mus, Pictures -> pic,
Videos -> vid, Templates/Public -> .ignoreme), hardcoded rather than read
from ~/.config/user-dirs.dirs -- that file is a separate, manually
tracked dotfile whose values can drift or go stale, and the migration
must not depend on it being correct. The nested Pictures/Screenshots
folder is renamed to pic/screenshots in the same pass.

Content left behind in a legacy full-named folder by a fresh XDG-defaults
install -- empty or not -- is merged into its short-named replacement.
A same-named collision between a legacy folder and its target is never
overwritten: it is skipped, reported, and the legacy folder is left in
place rather than deleted while something in it could not be merged.
--dry-run previews what would move/skip without touching the filesystem.
xdg-user-dirs-update runs once afterward to notify running apps/portals.
2026-07-06 16:31:35 -04:00

65 lines
3.3 KiB
Markdown

---
spec: dot-setup-folders
blocked-by: 000b-folders-unconditional-merge
---
## What to build
Stop reading the short-name target from `~/.config/user-dirs.dirs` and
hardcode the legacy-name -> short-name mapping directly in
`_dot_setup_folders`, dropping the dependency on that file entirely.
The original design treated the tracked `user-dirs.dirs` as the single
source of truth for target names, assuming someone would hand-edit it to
the short names before ever running the command. On this machine that
never happened: the tracked file still had the stock XDG defaults
(`XDG_DOCUMENTS_DIR="$HOME/Documents"`, etc.), so `target_path` resolved to
the exact same directory as `legacy_path` for every folder. The migration
logic then reported every entry as a "collision" against itself instead of
moving anything -- a confusing, silent-feeling failure rather than an
actual migration.
The short names are fixed (`.desktop`, `doc`, `dwn`, `mus`, `pic`, `vid`,
`.ignoreme`) and not meant to be configurable, so there's nothing to read
from a file in the first place. `user-dirs.dirs` remains a separate,
manually tracked dotfile (edited and tracked by hand, like any other
dotfile) for apps/`xdg-user-dirs-update` to consult -- `dot setup folders`
itself no longer reads it, requires its presence, or writes to it.
## Acceptance criteria
- [x] `_dot_setup_folders` no longer reads, parses, or requires
`~/.config/user-dirs.dirs`; the legacy->short-name mapping is a fixed
table in the function itself
- [x] Migration works identically whether `user-dirs.dirs` is absent,
empty, or declares stale/full-name values (the exact real-world case)
- [x] `user-dirs.dirs` is left byte-for-byte untouched by `dot setup
folders` when present, and no file is created when absent
- [x] `dot setup folders help` no longer describes reading target names
from `user-dirs.dirs`
- [x] `~/.config/dot/tests/dot.fish` no longer seeds a `user-dirs.dirs`
fixture as a migration precondition, and covers the stale/missing
cases above; `fishtape ~/.config/dot/tests/dot.fish` passes
## Implementation Notes
- Replaced the `xdg_vars`/`grep`/`string match` parsing of `user-dirs.dirs`
with two parallel hardcoded arrays, `legacy_names` and `target_names`,
indexed together -- same shape the code already used for `legacy_names`
alone, just extended to cover the target side too.
- The early `if not test -f $user_dirs; return 1` guard was deleted outright
rather than kept as a soft check: there's nothing left for the function to
read from that file, so requiring its existence would just be a
vestigial, unjustifiable precondition.
- Removed the `short_name_user_dirs` fixture and its seeding step from every
test scenario (it was previously duplicated into ~15 scenarios as a
migration precondition); added two new scenarios instead: one reproducing
the exact real-machine bug (stale full-name `user-dirs.dirs` values) and
one confirming migration works with no `user-dirs.dirs` file at all.
- Verified against this machine's real, still-stale `~/.config/user-dirs.dirs`
via `_dot_setup_folders --dry-run`: previously reported every entry in
Desktop/Documents/Downloads/Pictures/Videos as a collision against
itself; now correctly reports `would move N entries from ~/Documents to
~/doc` etc.
- `fishtape ~/.config/dot/tests/dot.fish` passes (183 tests).