Skip to content

feat: Installation Strategy Redesign - #15

Merged
sortedcord merged 18 commits into
masterfrom
fix/reference-counting
Jun 28, 2026
Merged

feat: Installation Strategy Redesign#15
sortedcord merged 18 commits into
masterfrom
fix/reference-counting

Conversation

@sortedcord

@sortedcord sortedcord commented Jun 26, 2026

Copy link
Copy Markdown
Owner

feat: Installation Strategy Redesign

This PR redesigns Bootstrap's installation system around explicit installation strategies, introducing a centralized registry, standardized GitHub release downloads, simplified package management, and a fully unified installation/uninstallation workflow.

The new architecture removes a significant amount of legacy compatibility code while making installers simpler, safer, and easier to extend.

Changes

Registry Infrastructure

  • Add lib/registry.sh that provides:

    • ensure_registry

      • Guarantees that registry.json exists.
      • Initializes it with { "tools": {} } if it does not already exist.
    • registry_set <jq_filter> [args...]

      • Thread-safe mutation wrapper.
      • Uses flock -x 200 to acquire an exclusive lock on registry.json.lock before executing the jq filter.
      • Prevents race conditions when multiple installers attempt to modify the registry simultaneously.
    • register_tool <tool_name> <strategy> [version] [source]

      • Registers or updates tool metadata.
      • Automatically records the installation timestamp.
      • Stores the binary path automatically for binary strategy tools.
    • registry_add_sys_deps <tool_name> <dep1> <dep2>...

      • Safely appends one or more system package dependencies.
    • registry_remove_tool <tool_name>

      • Completely removes a tool's entry from the registry.
    • registry_get_sys_deps <tool_name>

      • Outputs each recorded system dependency on its own line.
      • Used for dependency reference counting during uninstallation.
    • registry_check <tool_name>

      • Validates that a tool is correctly installed according to its declared strategy.
      Strategy Validation
      binary Confirms the registered binary exists and is executable.
      managed Confirms the tool is available via command -v.
      system Validates recorded system packages using pkg_check, falling back to command -v when no dependencies are recorded.

      Returns 0 if all checks pass, otherwise 1.

GitHub Release Helper

  • Add a shared lib/github.sh helper to standardize downloading the latest GitHub release binary.

    github_download_binary \
        "owner/repo" \
        "asset_pattern" \
        "$dest"
  • Migrate installers to use the shared helper instead of duplicating GitHub release logic.

Installer Migration

  • Introduce explicit installation strategies for installers.
  • Migrate all installers to use the new registry helpers.
  • Remove legacy backwards compatibility code.
  • Unify fragmented installation strategies across installers.
  • Prefer GitHub release binaries where appropriate (for example bat and yazi).
  • Remove redundant curl availability checks.
  • Remove standalone execution prevention blocks.
  • Remove obsolete configure shell code blocks.

Package Management

  • Simplify pkg_install and pkg_remove.
    • They now act as thin wrappers around the underlying package manager.
    • Registry state and rollback logic are no longer handled inside package management.
    • Reference counting only applies to system strategy dependencies.

Uninstallation & Rollback

  • Unify rollback and uninstall into a single workflow.
  • b rb <tool> can now uninstall individual tools.
  • Support uninstalling multiple tools with comma-separated arguments.
  • Preserve shared system dependencies until the last dependent tool is removed.
  • Prevent savepoints from being named after installed tools.
  • Improve validation in pkg_remove.
  • Fix checkpoint naming edge cases.

XDG Directory Layout

  • Migrate Bootstrap to an isolated XDG-compliant directory structure.
Variable Default Purpose
BOOTSTRAP_DIR ~/.config/bootstrap Config, shell snippets, libraries
BOOTSTRAP_DATA_DIR ~/.local/share/bootstrap Binaries, runtimes, optional installs
BOOTSTRAP_STATE_DIR ~/.local/state/bootstrap Registry, logs, rollback state
BOOTSTRAP_CACHE_DIR ~/.cache/bootstrap Download cache and temporary files
BOOTSTRAP_BIN $BOOTSTRAP_DATA_DIR/bin Installed binaries
BOOTSTRAP_OPT $BOOTSTRAP_DATA_DIR/opt Multi-file installations
BOOTSTRAP_RUNTIMES $BOOTSTRAP_DATA_DIR/runtimes Managed runtime homes
  • Add defensive fallbacks for undefined Bootstrap directory variables.
  • Remove the legacy BOOTSTRAP_PACKAGES_DIR.

Other Changes

  • Replace lib/json.sh with jq.
  • General linting and code cleanup.

Closes

Closes #1
Closes #9
Closes #14
Closes #16
Closes #18
Closes #19

@sortedcord sortedcord added this to the Release v3 milestone Jun 26, 2026
This was linked to issues Jun 26, 2026
While json.sh worked decently for reading json files, I didn't want to
implement writing to json files as well and make it completely
unreadable due to the added complexity.

So, I think its better to just use jq and keep things relatively simple
with the tradeoff of a lightweight dependency
bat and yazi installers use latest binary releases from github over
package manager for arch and fedora
Remove the configure shell code blocks
- Using $BOOTSTRAP_BIN, $BOOTSTRAP_OPT, etc
- Add defensive fallback for undefined vars in common.sh
@sortedcord

Copy link
Copy Markdown
Owner Author

Bootstrap is now using XDG Compliant and Isolated directory structure

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

closes #18

`pkg_install` and `pkg_remove` are just wrappers that map aliases and
directly invooke the system package manager.

- They do not manage state or inject rollback commands
- Removed `BOOTSTRAP_PACKAGES_DIR`
b rb <tool> can now uninstall that particular tool
@sortedcord sortedcord added the enhancement Improvement to an existing feature label Jun 26, 2026
@sortedcord

sortedcord commented Jun 26, 2026

Copy link
Copy Markdown
Owner Author

Improved rollback command to also act as an uninstall command for individual tools. (closes #19)

  • Added checks preventing savepoints from being named as tools
  • Multi tool uninstall (b rb tool_a,tool_b,tool_c)

- If multiple uninstalled tools share a system dependency, the
dependency is only uninstalled once the last tool using it is removed.
@sortedcord sortedcord changed the title WIP: Installation Strategy Redesign feat: Installation Strategy Redesign Jun 28, 2026
@sortedcord
sortedcord marked this pull request as ready for review June 28, 2026 02:21
Update hyperfine installer to follow the new installer strategy redesign
Update registry
@sortedcord
sortedcord merged commit 7d4e23e into master Jun 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement Improvement to an existing feature

Projects

Status: Done

1 participant