Skip to content

Migrate filesystem layout to XDG-compliant, fully isolated directory structure #18

Description

@sortedcord

Bootstrap currently scatters files across multiple unrelated locations in the user's home directory:

  • Binaries go to ~/.local/bin/, polluting a directory the user may already use for their own executables
  • Neovim + asciinema require sudo to install into /opt/nvim and /usr/local/bin
  • Managed runtimes colonize the home directory root: ~/.nvm/, ~/.cargo/, ~/.rustup/
  • pnpm lives in ~/.local/share/pnpm — isolated from the rest of Bootstrap's data
  • Mutable state (registry.json) is stored in ~/.config/bootstrap/, which is semantically wrong — .config is for configuration, not runtime state
  • Multiple installers each write their own redundant env.d/local-bin.sh snippet to add ~/.local/bin to PATH

This fragmentation makes clean uninstallation impossible without a manifest, violates the XDG Base Directory Specification, and contradicts Bootstrap's core principle of being a single, nukeable, fully isolated system.

Proposed Layout

~/.config/bootstrap/                  # Lightweight config only
├── b.sh                              # CLI entrypoint
├── VERSION
├── env.d/*.sh                        # Modular PATH/env snippets
├── aliases.d/*.sh                    # Modular alias snippets
├── lib/                              # Bootstrap libraries
├── installers/                       # Cached installer scripts
├── commands/                         # CLI subcommands
└── plugins/                          # Plugin scripts

~/.local/share/bootstrap/             # Heavy storage (binaries, runtimes)
├── bin/                              # All standalone binaries
├── opt/                              # Multi-file installations (e.g. nvim/)
├── runtimes/                         # Managed tool homes (nvm/, cargo/, rustup/, pnpm/)
└── completions/                      # Shell completions (future)

~/.local/state/bootstrap/             # Mutable state
├── registry.json                     # Tool manifest
├── logs/                             # Installation logs
└── rollback/                         # Rollback state

~/.cache/bootstrap/                   # Disposable cache
├── downloads/                        # Cached archives
└── tmp/                              # Temp working dirs

Environment Variables

Variable Default Purpose
BOOTSTRAP_DIR ~/.config/bootstrap Config, shell snippets, libs
BOOTSTRAP_DATA_DIR ~/.local/share/bootstrap Binaries, runtimes, opt
BOOTSTRAP_STATE_DIR ~/.local/state/bootstrap Registry, logs, rollback
BOOTSTRAP_CACHE_DIR ~/.cache/bootstrap Download cache, temp dirs
BOOTSTRAP_BIN $BOOTSTRAP_DATA_DIR/bin Binary executables
BOOTSTRAP_OPT $BOOTSTRAP_DATA_DIR/opt Multi-file installs
BOOTSTRAP_RUNTIMES $BOOTSTRAP_DATA_DIR/runtimes Managed tool homes

Clean Removal

After this migration, full removal becomes:

rm -rf ~/.local/share/bootstrap      # All binaries and runtimes
rm -rf ~/.config/bootstrap           # Config and shell integration
rm -rf ~/.local/state/bootstrap      # State and registry
rm -rf ~/.cache/bootstrap            # Cache
sed -i '/bootstrap/d' ~/.bashrc      # Remove shell hook

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    Status
    Done

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions