From cee345e3f0ea7489003f00d7ca07dbb7e87620d3 Mon Sep 17 00:00:00 2001 From: Aditya Gupta Date: Sat, 27 Jun 2026 00:20:56 +0530 Subject: [PATCH] feat: Unified Uninstallation and Rollback - Removed `BOOTSTRAP_PACKAGES_DIR` b rb can now uninstall that particular tool --- lib/rollback.sh | 48 ++++++++++++++++++++++++++++++++++++++++-------- lib/routes.sh | 7 ++++++- 2 files changed, 46 insertions(+), 9 deletions(-) diff --git a/lib/rollback.sh b/lib/rollback.sh index 8bd8cd6..d726a6c 100644 --- a/lib/rollback.sh +++ b/lib/rollback.sh @@ -8,11 +8,11 @@ _LIB_ROLLBACK_SOURCED=1 BOOTSTRAP_STATE_DIR="$HOME/.local/state/bootstrap" BOOTSTRAP_HISTORY_LOG="$BOOTSTRAP_STATE_DIR/history.log" BOOTSTRAP_UNINSTALLERS_DIR="$BOOTSTRAP_STATE_DIR/uninstallers" -BOOTSTRAP_PACKAGES_DIR="$BOOTSTRAP_STATE_DIR/packages" + init_rollback_system() { mkdir -p "$BOOTSTRAP_UNINSTALLERS_DIR" - mkdir -p "$BOOTSTRAP_PACKAGES_DIR" + touch "$BOOTSTRAP_HISTORY_LOG" } @@ -84,6 +84,41 @@ execute_rollback() { log_success "Rollback of '$tool' complete." } + +uninstall_tool() { + local tool="$1" + + # 1. Execute the rollback manifest to remove files/dirs/env/aliases + execute_rollback "$tool" + + # 2. Reference counting and cleanup of system dependencies + local registry_file="$BOOTSTRAP_STATE_DIR/registry.json" + if [ -f "$registry_file" ] && jq -e --arg tool "$tool" '.tools | has($tool)' "$registry_file" >/dev/null; then + while IFS= read -r dep; do + [ -z "$dep" ] && continue + local other_users + other_users=$(jq -r --arg tool "$tool" --arg dep "$dep" ' + .tools | to_entries | map(select(.key != $tool and (.value.system_dependencies | type == "array") and (.value.system_dependencies | index($dep)))) | length + ' "$registry_file") + + if [ "$other_users" -eq 0 ]; then + log_info "System dependency '$dep' is no longer required by any registered tool. Removing..." + pkg_remove "$dep" + else + log_info "Keeping system dependency '$dep' (required by other tools)" + fi + done < <(registry_get_sys_deps "$tool") + + # Remove from registry + registry_remove_tool "$tool" + fi + + # 3. Remove the tool from history.log + if [ -f "$BOOTSTRAP_HISTORY_LOG" ]; then + sed -i "/^INSTALL: ${tool}$/d" "$BOOTSTRAP_HISTORY_LOG" + fi +} + rollback_bare() { if [ ! -s "$BOOTSTRAP_HISTORY_LOG" ]; then log_info "No history available to rollback." @@ -95,9 +130,7 @@ rollback_bare() { if [[ "$last_line" == INSTALL:* ]]; then local tool="${last_line#INSTALL: }" - execute_rollback "$tool" - # Remove the last line efficiently - sed -i '$ d' "$BOOTSTRAP_HISTORY_LOG" + uninstall_tool "$tool" elif [[ "$last_line" == SAVEPOINT:* ]]; then local sp="${last_line#SAVEPOINT: }" log_warn "Last action was savepoint '$sp'. Cannot bare-rollback a savepoint." @@ -122,8 +155,7 @@ rollback_to_savepoint() { break elif [[ "$last_line" == INSTALL:* ]]; then local tool="${last_line#INSTALL: }" - execute_rollback "$tool" - sed -i '$ d' "$BOOTSTRAP_HISTORY_LOG" + uninstall_tool "$tool" elif [[ "$last_line" == SAVEPOINT:* ]]; then local sp="${last_line#SAVEPOINT: }" log_info "Removing intermediate savepoint '$sp'..." @@ -135,4 +167,4 @@ rollback_to_savepoint() { done } -export -f init_rollback_system setup_uninstaller_context add_rollback_cmd track_file track_dir create_savepoint mark_install_success execute_rollback rollback_bare rollback_to_savepoint +export -f init_rollback_system setup_uninstaller_context add_rollback_cmd track_file track_dir create_savepoint mark_install_success execute_rollback uninstall_tool rollback_bare rollback_to_savepoint diff --git a/lib/routes.sh b/lib/routes.sh index d41cf80..157a747 100755 --- a/lib/routes.sh +++ b/lib/routes.sh @@ -275,7 +275,12 @@ for script in "${SCRIPTS[@]}"; do if [ -z "$target" ]; then rollback_bare else - rollback_to_savepoint "$target" + local registry_file="$BOOTSTRAP_STATE_DIR/registry.json" + if [ -f "$registry_file" ] && jq -e --arg t "$target" '.tools | has($t)' "$registry_file" >/dev/null; then + uninstall_tool "$target" + else + rollback_to_savepoint "$target" + fi fi exit 0 ;;