mirror of
https://github.com/acedanger/shell.git
synced 2025-12-05 22:50:18 -08:00
feat: Add uninstall script for Fabric AI CLI with logging and OS detection
This commit is contained in:
214
uninstall-fabric.sh
Executable file
214
uninstall-fabric.sh
Executable file
@@ -0,0 +1,214 @@
|
||||
#!/bin/bash
|
||||
|
||||
# uninstall-fabric.sh
|
||||
#
|
||||
# Description: Safely uninstalls the Fabric AI CLI (Daniel Miessler) and related configuration.
|
||||
# Avoids removing the 'fabric' Python deployment library.
|
||||
# Detects OS and uses appropriate package managers if applicable.
|
||||
# Logs all actions to a file.
|
||||
#
|
||||
# Usage: ./uninstall-fabric.sh
|
||||
#
|
||||
# Author: GitHub Copilot
|
||||
|
||||
set -u
|
||||
|
||||
# Configuration
|
||||
LOG_FILE="uninstall-fabric.log"
|
||||
CURRENT_DATE=$(date +'%Y-%m-%d %H:%M:%S')
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Initialize log file
|
||||
echo "Fabric AI CLI Uninstallation Log - Started at $CURRENT_DATE" > "$LOG_FILE"
|
||||
|
||||
# Logging functions
|
||||
log() {
|
||||
local message="$1"
|
||||
echo -e "[$(date +'%H:%M:%S')] $message" | tee -a "$LOG_FILE"
|
||||
}
|
||||
|
||||
info() {
|
||||
local message="$1"
|
||||
echo -e "${BLUE}[INFO]${NC} $message" | tee -a "$LOG_FILE"
|
||||
}
|
||||
|
||||
success() {
|
||||
local message="$1"
|
||||
echo -e "${GREEN}[SUCCESS]${NC} $message" | tee -a "$LOG_FILE"
|
||||
}
|
||||
|
||||
warning() {
|
||||
local message="$1"
|
||||
echo -e "${YELLOW}[WARNING]${NC} $message" | tee -a "$LOG_FILE"
|
||||
}
|
||||
|
||||
error() {
|
||||
local message="$1"
|
||||
echo -e "${RED}[ERROR]${NC} $message" | tee -a "$LOG_FILE"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Function to detect Operating System
|
||||
detect_os() {
|
||||
if [[ -f /etc/os-release ]]; then
|
||||
# shellcheck source=/dev/null
|
||||
. /etc/os-release
|
||||
OS_NAME=$ID
|
||||
VERSION_ID=$VERSION_ID
|
||||
info "Detected OS: $NAME ($ID) $VERSION_ID"
|
||||
else
|
||||
error "Could not detect operating system. /etc/os-release file not found."
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to check for root privileges
|
||||
check_privileges() {
|
||||
if [[ $EUID -ne 0 ]]; then
|
||||
warning "This script is not running as root."
|
||||
warning "System package removal might fail or require sudo password."
|
||||
else
|
||||
info "Running with root privileges."
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to confirm action
|
||||
confirm_execution() {
|
||||
echo -e "\n${YELLOW}WARNING: This script will attempt to uninstall the Fabric AI CLI (Daniel Miessler).${NC}"
|
||||
echo -e "It will NOT remove the 'fabric' Python deployment library."
|
||||
echo -e "It will remove the 'fabric' binary if identified as the AI tool, and configuration files."
|
||||
echo -e "Please ensure you have backups if necessary.\n"
|
||||
|
||||
read -p "Do you want to proceed? (y/N): " -n 1 -r
|
||||
echo
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
info "Operation cancelled by user."
|
||||
exit 0
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to check if a binary is the Fabric AI tool
|
||||
is_fabric_ai_tool() {
|
||||
local bin_path="$1"
|
||||
# Check help output for keywords
|
||||
# The AI tool usually mentions 'patterns', 'context', 'session', 'model'
|
||||
if "$bin_path" --help 2>&1 | grep -qE "Daniel Miessler|patterns|context|session|model"; then
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
# Function to uninstall binary
|
||||
uninstall_binary() {
|
||||
local bin_path
|
||||
bin_path=$(command -v fabric)
|
||||
|
||||
if [[ -n "$bin_path" ]]; then
|
||||
info "Found 'fabric' binary at: $bin_path"
|
||||
|
||||
if is_fabric_ai_tool "$bin_path"; then
|
||||
info "Identified as Fabric AI CLI."
|
||||
|
||||
# Check if owned by system package
|
||||
local pkg_owner=""
|
||||
if [[ "$OS_NAME" =~ (debian|ubuntu|linuxmint|pop|kali) ]]; then
|
||||
if dpkg -S "$bin_path" &> /dev/null; then
|
||||
pkg_owner=$(dpkg -S "$bin_path" | cut -d: -f1)
|
||||
fi
|
||||
elif [[ "$OS_NAME" =~ (fedora|centos|rhel|almalinux|rocky) ]]; then
|
||||
if rpm -qf "$bin_path" &> /dev/null; then
|
||||
pkg_owner=$(rpm -qf "$bin_path")
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -n "$pkg_owner" ]]; then
|
||||
info "Binary is owned by system package: $pkg_owner"
|
||||
info "Removing package $pkg_owner..."
|
||||
local sudo_prefix=""
|
||||
[[ $EUID -ne 0 ]] && sudo_prefix="sudo"
|
||||
|
||||
if [[ "$OS_NAME" =~ (debian|ubuntu|linuxmint|pop|kali) ]]; then
|
||||
$sudo_prefix apt-get remove -y "$pkg_owner" >> "$LOG_FILE" 2>&1 || error "Failed to remove package $pkg_owner"
|
||||
else
|
||||
$sudo_prefix dnf remove -y "$pkg_owner" >> "$LOG_FILE" 2>&1 || error "Failed to remove package $pkg_owner"
|
||||
fi
|
||||
success "Removed system package $pkg_owner."
|
||||
else
|
||||
info "Binary is not owned by a system package. Removing manually..."
|
||||
rm -f "$bin_path" || error "Failed to remove $bin_path"
|
||||
success "Removed binary $bin_path."
|
||||
fi
|
||||
else
|
||||
warning "The binary at $bin_path does not appear to be the Fabric AI CLI. Skipping removal to be safe."
|
||||
warning "Run '$bin_path --help' to verify what it is."
|
||||
fi
|
||||
else
|
||||
info "'fabric' binary not found in PATH."
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to uninstall from pipx
|
||||
uninstall_pipx() {
|
||||
if command -v pipx &> /dev/null; then
|
||||
info "Checking pipx for 'fabric'..."
|
||||
if pipx list | grep -q "package fabric"; then
|
||||
info "Found 'fabric' installed via pipx. Uninstalling..."
|
||||
pipx uninstall fabric >> "$LOG_FILE" 2>&1 || error "Failed to uninstall fabric via pipx"
|
||||
success "Uninstalled fabric via pipx."
|
||||
else
|
||||
info "'fabric' not found in pipx."
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to remove configuration files
|
||||
remove_config() {
|
||||
local config_dirs=(
|
||||
"$HOME/.config/fabric"
|
||||
"$HOME/.fabric"
|
||||
"$HOME/.local/share/fabric"
|
||||
)
|
||||
|
||||
for dir in "${config_dirs[@]}"; do
|
||||
if [[ -d "$dir" ]]; then
|
||||
info "Found configuration directory: $dir"
|
||||
rm -rf "$dir" || error "Failed to remove $dir"
|
||||
success "Removed $dir."
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# Main execution flow
|
||||
main() {
|
||||
detect_os
|
||||
check_privileges
|
||||
confirm_execution
|
||||
|
||||
info "Starting uninstallation process..."
|
||||
|
||||
# Check pipx first as it manages its own binaries
|
||||
uninstall_pipx
|
||||
|
||||
# Check binary
|
||||
uninstall_binary
|
||||
|
||||
# Remove config
|
||||
remove_config
|
||||
|
||||
echo -e "\n----------------------------------------------------------------"
|
||||
success "Uninstallation steps completed."
|
||||
info "A log of this operation has been saved to: $LOG_FILE"
|
||||
echo -e "${YELLOW}Note: If you removed system-level components, a reboot might be recommended.${NC}"
|
||||
echo -e "----------------------------------------------------------------"
|
||||
}
|
||||
|
||||
# Trap interrupts
|
||||
trap 'echo -e "\n${RED}Script interrupted by user.${NC}"; exit 1' INT TERM
|
||||
|
||||
# Run main
|
||||
main
|
||||
Reference in New Issue
Block a user