191 lines
5.3 KiB
Bash
Executable File
191 lines
5.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
||
|
||
set -euo pipefail
|
||
|
||
: "${HOME:=$PWD}"
|
||
|
||
# Zsh safety: allow empty globs (re-run safe)
|
||
setopt NULL_GLOB 2>/dev/null || true
|
||
|
||
SWITCHED_TO_ZSH="${SWITCHED_TO_ZSH:-0}"
|
||
|
||
# =========================================================
|
||
# FORCE ZSH ON MACOS (Finder-friendly)
|
||
# =========================================================
|
||
if [[ "${OSTYPE:-}" == darwin* && "$SWITCHED_TO_ZSH" -eq 0 && "$(ps -p $$ -o comm= 2>/dev/null || true)" != "zsh" ]]; then
|
||
export SWITCHED_TO_ZSH=1
|
||
exec env zsh "$0" "$@"
|
||
fi
|
||
|
||
# =========================================================
|
||
# SCRIPT PATH RESOLUTION (BASH + ZSH)
|
||
# =========================================================
|
||
if [[ -n "${BASH_SOURCE:-}" ]]; then
|
||
script_path="${BASH_SOURCE[0]}"
|
||
elif [[ -n "${ZSH_VERSION:-}" ]]; then
|
||
script_path="${(%):-%x}"
|
||
else
|
||
script_path="$0"
|
||
fi
|
||
|
||
APP_NAME="ebook2audiobook"
|
||
SCRIPT_DIR="$(cd "$(dirname "$script_path")" >/dev/null 2>&1 && pwd -P)"
|
||
SCRIPT_NAME="$(basename "$script_path")"
|
||
INSTALLED_LOG="$SCRIPT_DIR/.installed"
|
||
|
||
CONDA_HOME="$HOME/Miniforge3"
|
||
CONDA_BIN_PATH="$CONDA_HOME/bin"
|
||
|
||
# heavy directories deleted atomically (no traversal)
|
||
SKIP_DIRS=("python_env" "Miniforge3")
|
||
|
||
# macOS shortcuts (KNOWN, FIXED PATHS)
|
||
APP_BUNDLE="$HOME/Applications/$APP_NAME.app"
|
||
DESKTOP_ALIAS="$HOME/Desktop/ebook2audiobook"
|
||
|
||
# =========================================================
|
||
# HEADER
|
||
# =========================================================
|
||
echo
|
||
echo "========================================"
|
||
echo " $APP_NAME – Uninstaller"
|
||
echo "========================================"
|
||
echo "Install location:"
|
||
echo " $SCRIPT_DIR"
|
||
echo
|
||
|
||
# =========================================================
|
||
# USER CONFIRMATION
|
||
# =========================================================
|
||
if [[ -t 0 ]]; then
|
||
echo "This will uninstall $APP_NAME."
|
||
echo "Components listed in .installed will be removed."
|
||
echo
|
||
printf "Press Enter to continue or Ctrl+C to abort..."
|
||
read -r _ || true
|
||
echo
|
||
fi
|
||
|
||
# =========================================================
|
||
# macOS SHORTCUT CLEANUP (NO TESTS, GUARDED)
|
||
# =========================================================
|
||
if [[ "${OSTYPE:-}" == darwin* ]]; then
|
||
echo "Cleaning macOS shortcuts"
|
||
|
||
if [[ -n "$APP_BUNDLE" && "$APP_BUNDLE" != "/" ]]; then
|
||
rm -rf "$APP_BUNDLE" 2>/dev/null || true
|
||
fi
|
||
|
||
if [[ -n "$DESKTOP_ALIAS" && "$DESKTOP_ALIAS" != "/" ]]; then
|
||
rm -f "$DESKTOP_ALIAS" 2>/dev/null || true
|
||
fi
|
||
fi
|
||
|
||
# =========================================================
|
||
# LINUX SHORTCUT CLEANUP (NO TESTS, GUARDED)
|
||
# =========================================================
|
||
if [[ "${OSTYPE:-}" == linux* ]]; then
|
||
echo "Cleaning Linux shortcuts"
|
||
|
||
if [[ -n "$DESKTOP_ALIAS" && "$DESKTOP_ALIAS" != "/" ]]; then
|
||
rm -f "$DESKTOP_ALIAS" 2>/dev/null || true
|
||
fi
|
||
fi
|
||
|
||
# =========================================================
|
||
# PROCESS .installed (CONTROLLED REMOVAL)
|
||
# =========================================================
|
||
REMOVE_CONDA=0
|
||
if [[ -f "$INSTALLED_LOG" ]] && grep -iqF "Miniforge3" "$INSTALLED_LOG"; then
|
||
REMOVE_CONDA=1
|
||
fi
|
||
|
||
# =========================================================
|
||
# SAFE PATH CLEANUP
|
||
# =========================================================
|
||
remove_from_path() {
|
||
local target="$1"
|
||
# Refuse to operate on empty or dangerous targets
|
||
[[ -z "$target" ]] && return 0
|
||
case "$target" in
|
||
/|/bin|/usr/bin|/sbin|/usr/sbin|/usr/local/bin) return 0 ;;
|
||
esac
|
||
local new_path=""
|
||
local rest="${PATH:-}"
|
||
local p
|
||
while [[ -n "$rest" ]]; do
|
||
if [[ "$rest" == *:* ]]; then
|
||
p="${rest%%:*}"
|
||
rest="${rest#*:}"
|
||
else
|
||
p="$rest"
|
||
rest=""
|
||
fi
|
||
[[ -z "$p" ]] && continue
|
||
[[ "$p" == "$target" ]] && continue
|
||
new_path="${new_path:+$new_path:}$p"
|
||
done
|
||
PATH="$new_path"
|
||
export PATH
|
||
}
|
||
|
||
# =========================================================
|
||
# FAST DELETE HEAVY REPO DIRS (NO LISTING)
|
||
# =========================================================
|
||
for d in "${SKIP_DIRS[@]}"; do
|
||
path="$SCRIPT_DIR/$d"
|
||
if [[ -n "$path" && "$path" != "/" ]]; then
|
||
rm -rf "$path" 2>/dev/null || true
|
||
fi
|
||
done
|
||
|
||
# =========================================================
|
||
# CLEAN REPOSITORY CONTENT (FIRST LEVEL ONLY)
|
||
# =========================================================
|
||
echo
|
||
echo "Cleaning repository content..."
|
||
|
||
# Make unmatched globs expand to nothing instead of erroring (zsh) or staying literal (bash)
|
||
if [[ -n "${ZSH_VERSION:-}" ]]; then
|
||
setopt local_options null_glob
|
||
else
|
||
shopt -s nullglob 2>/dev/null || true
|
||
fi
|
||
|
||
for item in "$SCRIPT_DIR"/* "$SCRIPT_DIR"/.*; do
|
||
name="${item##*/}"
|
||
[[ "$name" == "." || "$name" == ".." ]] && continue
|
||
[[ "$name" == "$SCRIPT_NAME" ]] && continue
|
||
echo "-> $item"
|
||
if [[ -n "$item" && "$item" != "/" ]]; then
|
||
/bin/rm -rf "$item"
|
||
fi
|
||
done
|
||
|
||
# remove .installed if still present
|
||
if [[ -n "$INSTALLED_LOG" && "$INSTALLED_LOG" != "/" ]]; then
|
||
rm -f "$INSTALLED_LOG" 2>/dev/null || true
|
||
fi
|
||
|
||
# =========================================================
|
||
# FINAL MESSAGE
|
||
# =========================================================
|
||
echo
|
||
echo "================================================"
|
||
echo " Uninstallation completed."
|
||
echo
|
||
echo " The application content has been removed."
|
||
echo " Please remove the empty repository folder manually:"
|
||
echo
|
||
echo " $SCRIPT_DIR"
|
||
echo
|
||
echo "================================================"
|
||
echo
|
||
|
||
if [[ -t 0 ]]; then
|
||
printf "Press Enter to continue..."
|
||
read -r _ || true
|
||
fi
|
||
|
||
exit 0
|