drewthomasson--ebook2audiobook
191 行
5.3 KiB
Bash
可执行文件
191 行
5.3 KiB
Bash
可执行文件
#!/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
|