Files
drip/scripts/install-client.sh

899 lines
27 KiB
Bash
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
set -e
# ============================================================================
# Configuration
# ============================================================================
GITHUB_REPO="Gouryella/drip"
INSTALL_DIR="${INSTALL_DIR:-}"
VERSION="${VERSION:-}"
BINARY_NAME="drip"
UNINSTALL_MODE=false
COMMAND_MADE_AVAILABLE=false
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
CYAN='\033[0;36m'
BOLD='\033[1m'
NC='\033[0m'
# Language (default: en)
LANG_CODE="${LANG_CODE:-en}"
# ============================================================================
# Internationalization
# ============================================================================
msg_en() {
case "$1" in
banner_title) echo "Drip Client - One-Click Installer" ;;
select_lang) echo "Select language / 选择语言" ;;
lang_en) echo "English" ;;
lang_zh) echo "中文" ;;
checking_os) echo "Checking operating system..." ;;
detected_os) echo "Detected OS" ;;
unsupported_os) echo "Unsupported operating system" ;;
checking_arch) echo "Checking system architecture..." ;;
detected_arch) echo "Detected architecture" ;;
unsupported_arch) echo "Unsupported architecture" ;;
checking_deps) echo "Checking dependencies..." ;;
deps_ok) echo "Dependencies check passed" ;;
downloading) echo "Downloading Drip client" ;;
download_failed) echo "Download failed" ;;
download_ok) echo "Download completed" ;;
select_install_dir) echo "Select installation directory" ;;
option_user) echo "User directory (no sudo required)" ;;
option_system) echo "System directory (requires sudo)" ;;
option_current) echo "Current directory" ;;
option_custom) echo "Custom path" ;;
enter_custom_path) echo "Enter custom path" ;;
installing) echo "Installing binary..." ;;
install_ok) echo "Installation completed" ;;
updating_path) echo "Updating PATH..." ;;
path_updated) echo "PATH updated" ;;
path_note) echo "Please restart your terminal or run: source ~/.bashrc" ;;
config_title) echo "Client Configuration" ;;
configure_now) echo "Configure client now?" ;;
enter_server) echo "Enter server address (e.g., tunnel.example.com:8443)" ;;
server_required) echo "Server address is required" ;;
enter_token) echo "Enter authentication token" ;;
token_required) echo "Token is required" ;;
skip_verify) echo "Skip TLS certificate verification? (for self-signed certs)" ;;
config_saved) echo "Configuration saved" ;;
install_complete) echo "Installation completed!" ;;
usage_title) echo "Usage" ;;
usage_http) echo "Expose HTTP service on port 3000" ;;
usage_tcp) echo "Expose TCP service on port 5432" ;;
usage_config) echo "Show/modify configuration" ;;
usage_daemon) echo "Run as background daemon" ;;
run_test) echo "Test connection now?" ;;
test_running) echo "Testing connection..." ;;
test_success) echo "Connection successful" ;;
test_failed) echo "Connection failed" ;;
yes) echo "y" ;;
no) echo "n" ;;
press_enter) echo "Press Enter to continue..." ;;
windows_note) echo "For Windows, please download the .exe file from GitHub Releases" ;;
already_installed) echo "Drip is already installed" ;;
current_version) echo "Current version" ;;
update_now) echo "Update to the latest version?" ;;
updating) echo "Updating..." ;;
update_ok) echo "Update completed" ;;
verify_install) echo "Verifying installation..." ;;
verify_ok) echo "Verification passed" ;;
verify_failed) echo "Verification failed" ;;
insecure_note) echo "Only use --insecure for development/testing" ;;
uninstall_title) echo "Drip Client - Uninstall" ;;
uninstall_prompt) echo "Uninstall Drip client now?" ;;
uninstalling) echo "Uninstalling Drip client..." ;;
uninstall_done) echo "Uninstall completed" ;;
uninstall_not_found) echo "Drip is not installed" ;;
remove_config_prompt) echo "Remove Drip config directory as well?" ;;
config_removed) echo "Config removed" ;;
path_cleanup) echo "Cleaning PATH entries..." ;;
path_cleanup_done) echo "PATH entries cleaned" ;;
*) echo "$1" ;;
esac
}
msg_zh() {
case "$1" in
banner_title) echo "Drip 客户端 - 一键安装脚本" ;;
select_lang) echo "Select language / 选择语言" ;;
lang_en) echo "English" ;;
lang_zh) echo "中文" ;;
checking_os) echo "检查操作系统..." ;;
detected_os) echo "检测到操作系统" ;;
unsupported_os) echo "不支持的操作系统" ;;
checking_arch) echo "检查系统架构..." ;;
detected_arch) echo "检测到架构" ;;
unsupported_arch) echo "不支持的架构" ;;
checking_deps) echo "检查依赖..." ;;
deps_ok) echo "依赖检查通过" ;;
downloading) echo "下载 Drip 客户端" ;;
download_failed) echo "下载失败" ;;
download_ok) echo "下载完成" ;;
select_install_dir) echo "选择安装目录" ;;
option_user) echo "用户目录(无需 sudo" ;;
option_system) echo "系统目录(需要 sudo" ;;
option_current) echo "当前目录" ;;
option_custom) echo "自定义路径" ;;
enter_custom_path) echo "输入自定义路径" ;;
installing) echo "安装二进制文件..." ;;
install_ok) echo "安装完成" ;;
updating_path) echo "更新 PATH..." ;;
path_updated) echo "PATH 已更新" ;;
path_note) echo "请重启终端或运行: source ~/.bashrc" ;;
config_title) echo "客户端配置" ;;
configure_now) echo "现在配置客户端?" ;;
enter_server) echo "输入服务器地址例如tunnel.example.com:8443" ;;
server_required) echo "服务器地址是必填项" ;;
enter_token) echo "输入认证令牌" ;;
token_required) echo "认证令牌是必填项" ;;
skip_verify) echo "跳过 TLS 证书验证?(用于自签名证书)" ;;
config_saved) echo "配置已保存" ;;
install_complete) echo "安装完成!" ;;
usage_title) echo "使用方法" ;;
usage_http) echo "暴露本地 3000 端口的 HTTP 服务" ;;
usage_tcp) echo "暴露本地 5432 端口的 TCP 服务" ;;
usage_config) echo "显示/修改配置" ;;
usage_daemon) echo "作为后台守护进程运行" ;;
run_test) echo "现在测试连接?" ;;
test_running) echo "正在测试连接..." ;;
test_success) echo "连接成功" ;;
test_failed) echo "连接失败" ;;
yes) echo "y" ;;
no) echo "n" ;;
press_enter) echo "按 Enter 继续..." ;;
windows_note) echo "Windows 用户请从 GitHub Releases 下载 .exe 文件" ;;
already_installed) echo "Drip 已安装" ;;
current_version) echo "当前版本" ;;
update_now) echo "是否更新到最新版本?" ;;
updating) echo "正在更新..." ;;
update_ok) echo "更新完成" ;;
verify_install) echo "验证安装..." ;;
verify_ok) echo "验证通过" ;;
verify_failed) echo "验证失败" ;;
insecure_note) echo "--insecure 仅用于开发/测试环境" ;;
uninstall_title) echo "Drip 客户端 - 卸载" ;;
uninstall_prompt) echo "现在卸载 Drip 客户端?" ;;
uninstalling) echo "正在卸载 Drip 客户端..." ;;
uninstall_done) echo "卸载完成" ;;
uninstall_not_found) echo "未检测到已安装的 Drip" ;;
remove_config_prompt) echo "是否同时删除 Drip 配置目录?" ;;
config_removed) echo "配置已删除" ;;
path_cleanup) echo "清理 PATH 相关配置..." ;;
path_cleanup_done) echo "PATH 配置已清理" ;;
*) echo "$1" ;;
esac
}
# Get message by key (bash 3.2 compatible)
msg() {
local key="$1"
if [[ "$LANG_CODE" == "zh" ]]; then
msg_zh "$key"
else
msg_en "$key"
fi
}
# Prompt helper compatible with bash 3.2 and zsh
prompt_input() {
local __prompt="$1"
local __var_name="$2"
printf "%s" "$__prompt"
IFS= read -r "$__var_name" < /dev/tty
}
# ============================================================================
# Output functions
# ============================================================================
print_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
print_success() { echo -e "${GREEN}[✓]${NC} $1"; }
print_warning() { echo -e "${YELLOW}[!]${NC} $1"; }
print_error() { echo -e "${RED}[✗]${NC} $1"; }
print_step() { echo -e "${CYAN}[→]${NC} $1"; }
repeat_char() {
local char="$1"
local count="$2"
local out=""
for _ in $(seq 1 "$count"); do
out+="$char"
done
echo "$out"
}
print_panel() {
local title="$1"
shift
local width=58
local bar
bar=$(repeat_char "=" "$width")
echo ""
echo -e "${CYAN}${bar}${NC}"
echo -e "${CYAN}${title}${NC}"
echo -e "${CYAN}${bar}${NC}"
for line in "$@"; do
echo -e " $line"
done
echo -e "${CYAN}${bar}${NC}"
echo ""
}
print_subheader() {
local title="$1"
local width=58
local bar
bar=$(repeat_char "-" "$width")
echo ""
echo -e "${CYAN}${title}${NC}"
echo -e "${CYAN}${bar}${NC}"
}
# Print banner
print_banner() {
echo -e "${GREEN}"
cat << "EOF"
____ _
/ __ \_____(_)___
/ / / / ___/ / __ \
/ /_/ / / / / /_/ /
/_____/_/ /_/ .___/
/_/
EOF
echo -e "${BOLD}$(msg banner_title)${NC}"
echo ""
}
# Extract version from a drip binary, preferring the plain output when available
get_version_from_binary() {
local binary="$1"
local output=""
local version=""
output=$("$binary" version --short 2>/dev/null || true)
if [[ -n "$output" ]]; then
version=$(printf '%s\n' "$output" | awk -F': ' '/Version/ {print $2; exit}')
fi
if [[ -z "$version" ]]; then
output=$("$binary" version 2>/dev/null || true)
if [[ -n "$output" ]]; then
output=$(printf '%s\n' "$output" | sed -E $'s/\x1b\\[[0-9;]*[A-Za-z]//g')
version=$(printf '%s\n' "$output" | sed -nE 's/.*Version:[[:space:]]*([vV]?[0-9][^[:space:]]*).*/\1/p' | head -n1)
fi
fi
echo "${version:-unknown}"
}
# ============================================================================
# Language selection
# ============================================================================
select_language() {
print_panel "$(msg select_lang)" \
"${GREEN}1)${NC} English" \
"${GREEN}2)${NC} 中文"
prompt_input "Select [1]: " lang_choice
case "$lang_choice" in
2)
LANG_CODE="zh"
;;
*)
LANG_CODE="en"
;;
esac
echo ""
}
# ============================================================================
# System checks
# ============================================================================
check_os() {
print_step "$(msg checking_os)"
case "$(uname -s)" in
Linux*)
OS="linux"
;;
Darwin*)
OS="darwin"
;;
MINGW*|MSYS*|CYGWIN*)
OS="windows"
print_warning "$(msg windows_note)"
;;
*)
print_error "$(msg unsupported_os): $(uname -s)"
exit 1
;;
esac
print_success "$(msg detected_os): $OS"
}
check_arch() {
print_step "$(msg checking_arch)"
case "$(uname -m)" in
x86_64|amd64)
ARCH="amd64"
;;
aarch64|arm64)
ARCH="arm64"
;;
armv7l)
ARCH="armv7"
;;
armv6l)
ARCH="armv6"
;;
i386|i686)
ARCH="386"
;;
*)
print_error "$(msg unsupported_arch): $(uname -m)"
exit 1
;;
esac
print_success "$(msg detected_arch): $ARCH"
}
check_dependencies() {
print_step "$(msg checking_deps)"
# Check for download tool
if ! command -v curl &> /dev/null && ! command -v wget &> /dev/null; then
print_error "curl or wget is required"
exit 1
fi
print_success "$(msg deps_ok)"
}
get_latest_version() {
# Get latest version from GitHub API
local api_url="https://api.github.com/repos/${GITHUB_REPO}/releases/latest"
local version=""
if command -v curl &> /dev/null; then
version=$(curl -fsSL "$api_url" | grep '"tag_name":' | sed -E 's/.*"tag_name": *"([^"]+)".*/\1/' 2>/dev/null)
else
version=$(wget -qO- "$api_url" | grep '"tag_name":' | sed -E 's/.*"tag_name": *"([^"]+)".*/\1/' 2>/dev/null)
fi
if [[ -z "$version" ]]; then
print_error "Failed to get latest version from GitHub"
exit 1
fi
echo "$version"
}
check_existing_install() {
if command -v drip &> /dev/null; then
local current_path=$(command -v drip)
local current_version=$(get_version_from_binary "drip")
print_warning "$(msg already_installed): $current_path"
print_info "$(msg current_version): $current_version"
# Check remote version
print_step "Checking for updates..."
local latest_version=$(get_latest_version)
if [[ "$current_version" == "$latest_version" ]]; then
print_success "Already up to date ($current_version)"
exit 0
else
print_info "Latest version: $latest_version"
echo ""
prompt_input "$(msg update_now) [Y/n]: " update_choice
fi
if [[ "$update_choice" =~ ^[Nn]$ ]]; then
exit 0
fi
INSTALL_DIR=$(dirname "$current_path")
IS_UPDATE=true
fi
}
# ============================================================================
# Download and install
# ============================================================================
get_download_url() {
# Get latest version if not set
if [[ -z "$VERSION" ]]; then
VERSION=$(get_latest_version)
fi
# Strip 'v' prefix for archive filename (v0.7.0 -> 0.7.0)
local version_number="${VERSION#v}"
local archive_name
local ext="tar.gz"
if [[ "$OS" == "windows" ]]; then
archive_name="drip_${version_number}_windows_${ARCH}.${ext}"
else
archive_name="drip_${version_number}_${OS}_${ARCH}.${ext}"
fi
echo "https://github.com/${GITHUB_REPO}/releases/download/${VERSION}/${archive_name}"
}
download_binary() {
local url=$(get_download_url)
if [[ "$IS_UPDATE" == true ]]; then
print_step "$(msg updating)..."
else
print_step "$(msg downloading)..."
fi
local tmp_archive="/tmp/drip-archive.tar.gz"
local tmp_dir="/tmp/drip-extract"
# Clean up any previous extraction
rm -rf "$tmp_dir"
mkdir -p "$tmp_dir"
if command -v curl &> /dev/null; then
# Use -# for progress bar instead of -s (silent)
if ! curl -f#L "$url" -o "$tmp_archive"; then
print_error "$(msg download_failed): $url"
exit 1
fi
else
# Use --show-progress to display download progress
if ! wget --show-progress "$url" -O "$tmp_archive" 2>&1 | grep -v "^$"; then
print_error "$(msg download_failed): $url"
exit 1
fi
fi
# Extract the archive
if ! tar -xzf "$tmp_archive" -C "$tmp_dir"; then
print_error "Failed to extract archive"
exit 1
fi
# Find the binary (it should be named 'drip' or 'drip.exe')
local extracted_binary=""
if [[ "$OS" == "windows" ]]; then
extracted_binary=$(find "$tmp_dir" -name "drip.exe" -type f 2>/dev/null | head -1)
else
extracted_binary=$(find "$tmp_dir" -name "drip" -type f 2>/dev/null | head -1)
fi
if [[ -z "$extracted_binary" ]]; then
print_error "Binary not found in archive"
exit 1
fi
# Move to standard location
mv "$extracted_binary" /tmp/drip-download
chmod +x /tmp/drip-download
# Clean up
rm -rf "$tmp_archive" "$tmp_dir"
print_success "$(msg download_ok)"
}
select_install_dir() {
if [[ -n "$INSTALL_DIR" ]]; then
return
fi
print_panel "$(msg select_install_dir)" \
"${GREEN}1)${NC} ~/.local/bin $(msg option_user)" \
"${GREEN}2)${NC} /usr/local/bin $(msg option_system)" \
"${GREEN}3)${NC} ./ $(msg option_current)" \
"${GREEN}4)${NC} $(msg option_custom)"
prompt_input "Select [1]: " dir_choice
case "$dir_choice" in
2)
INSTALL_DIR="/usr/local/bin"
NEED_SUDO=true
;;
3)
INSTALL_DIR="."
;;
4)
prompt_input "$(msg enter_custom_path): " INSTALL_DIR
;;
*)
INSTALL_DIR="$HOME/.local/bin"
;;
esac
}
install_binary() {
print_step "$(msg installing)"
# Create directory if needed
if [[ ! -d "$INSTALL_DIR" ]]; then
if [[ "$NEED_SUDO" == true ]]; then
sudo mkdir -p "$INSTALL_DIR"
else
mkdir -p "$INSTALL_DIR"
fi
fi
local target_path="$INSTALL_DIR/$BINARY_NAME"
if [[ "$OS" == "windows" ]]; then
target_path="$INSTALL_DIR/$BINARY_NAME.exe"
fi
# Install binary
if [[ "$NEED_SUDO" == true ]]; then
sudo mv /tmp/drip-download "$target_path"
sudo chmod +x "$target_path"
else
mv /tmp/drip-download "$target_path"
chmod +x "$target_path"
fi
print_success "$(msg install_ok): $target_path"
}
update_path() {
# Skip if already in PATH
if command -v drip &> /dev/null; then
return
fi
if [[ "$COMMAND_MADE_AVAILABLE" == true ]]; then
return
fi
# Skip for system directories (usually already in PATH)
if [[ "$INSTALL_DIR" == "/usr/local/bin" ]] || [[ "$INSTALL_DIR" == "/usr/bin" ]]; then
return
fi
print_step "$(msg updating_path)"
local shell_rc=""
local export_line="export PATH=\"\$PATH:$INSTALL_DIR\""
# Determine shell config file
if [[ -n "$ZSH_VERSION" ]] || [[ "$SHELL" == *"zsh"* ]]; then
shell_rc="$HOME/.zshrc"
elif [[ -n "$BASH_VERSION" ]] || [[ "$SHELL" == *"bash"* ]]; then
if [[ "$OS" == "darwin" ]]; then
shell_rc="$HOME/.bash_profile"
else
shell_rc="$HOME/.bashrc"
fi
elif [[ "$SHELL" == *"fish"* ]]; then
shell_rc="$HOME/.config/fish/config.fish"
export_line="set -gx PATH \$PATH $INSTALL_DIR"
fi
if [[ -n "$shell_rc" ]]; then
# Check if already added
if ! grep -q "$INSTALL_DIR" "$shell_rc" 2>/dev/null; then
echo "" >> "$shell_rc"
echo "# Drip client" >> "$shell_rc"
echo "$export_line" >> "$shell_rc"
print_success "$(msg path_updated): $shell_rc"
fi
fi
print_warning "$(msg path_note)"
}
ensure_command_access() {
# Try to make the command available immediately without requiring shell restart
if [[ "$OS" == "windows" ]]; then
return
fi
hash -r 2>/dev/null || true
command -v rehash >/dev/null 2>&1 && rehash || true
if command -v "$BINARY_NAME" >/dev/null 2>&1; then
COMMAND_MADE_AVAILABLE=true
return
fi
local target_path="$INSTALL_DIR/$BINARY_NAME"
local preferred="/usr/local/bin"
if [[ ":$PATH:" == *":$preferred:"* ]]; then
if [[ -w "$preferred" ]]; then
if ln -sf "$target_path" "$preferred/$BINARY_NAME" 2>/dev/null; then
COMMAND_MADE_AVAILABLE=true
print_success "Made ${BINARY_NAME} available at $preferred/$BINARY_NAME"
fi
else
if sudo ln -sf "$target_path" "$preferred/$BINARY_NAME" 2>/dev/null; then
COMMAND_MADE_AVAILABLE=true
print_success "Made ${BINARY_NAME} available at $preferred/$BINARY_NAME"
fi
fi
fi
# Refresh hash table
hash -r 2>/dev/null || true
command -v rehash >/dev/null 2>&1 && rehash || true
}
verify_installation() {
print_step "$(msg verify_install)"
local binary_path="$INSTALL_DIR/$BINARY_NAME"
if [[ "$OS" == "windows" ]]; then
binary_path="$INSTALL_DIR/$BINARY_NAME.exe"
fi
if [[ -x "$binary_path" ]]; then
local version=$(get_version_from_binary "$binary_path")
print_success "$(msg verify_ok): $version"
else
print_error "$(msg verify_failed)"
exit 1
fi
}
# ============================================================================
# Configuration
# ============================================================================
configure_client() {
echo ""
prompt_input "$(msg configure_now) [Y/n]: " config_choice
if [[ "$config_choice" =~ ^[Nn]$ ]]; then
return
fi
print_subheader "$(msg config_title)"
local binary_path="$INSTALL_DIR/$BINARY_NAME"
# Server address
while true; do
prompt_input "$(msg enter_server): " SERVER
if [[ -n "$SERVER" ]]; then
break
fi
print_error "$(msg server_required)"
done
# Token
while true; do
prompt_input "$(msg enter_token): " TOKEN
if [[ -n "$TOKEN" ]]; then
break
fi
print_error "$(msg token_required)"
done
# Insecure mode
prompt_input "$(msg skip_verify) [y/N]: " insecure_choice
INSECURE=""
if [[ "$insecure_choice" =~ ^[Yy]$ ]]; then
INSECURE="--insecure"
print_warning "$(msg insecure_note)"
fi
# Save configuration
"$binary_path" config set --server "$SERVER" --token "$TOKEN" $INSECURE 2>/dev/null || true
print_success "$(msg config_saved)"
}
# ============================================================================
# Test connection
# ============================================================================
test_connection() {
echo ""
prompt_input "$(msg run_test) [y/N]: " test_choice
if [[ ! "$test_choice" =~ ^[Yy]$ ]]; then
return
fi
print_step "$(msg test_running)"
local binary_path="$INSTALL_DIR/$BINARY_NAME"
# Try to validate config
if "$binary_path" config validate 2>/dev/null; then
print_success "$(msg test_success)"
else
print_warning "$(msg test_failed)"
fi
}
# ============================================================================
# Final output
# ============================================================================
show_completion() {
local binary_path="$INSTALL_DIR/$BINARY_NAME"
print_panel "$(msg install_complete)"
echo -e "${CYAN}$(msg usage_title):${NC}"
echo ""
echo -e " ${GREEN}# $(msg usage_http)${NC}"
echo -e " ${YELLOW}$BINARY_NAME http 3000${NC}"
echo ""
echo -e " ${GREEN}# $(msg usage_tcp)${NC}"
echo -e " ${YELLOW}$BINARY_NAME tcp 5432${NC}"
echo ""
echo -e " ${GREEN}# $(msg usage_config)${NC}"
echo -e " ${YELLOW}$BINARY_NAME config show${NC}"
echo -e " ${YELLOW}$BINARY_NAME config init${NC}"
echo ""
echo -e " ${GREEN}# $(msg usage_daemon)${NC}"
echo -e " ${YELLOW}$BINARY_NAME daemon start http 3000${NC}"
echo -e " ${YELLOW}$BINARY_NAME daemon list${NC}"
echo ""
}
# ============================================================================
# Uninstall
# ============================================================================
cleanup_path_entries() {
local install_dir="$1"
local candidates=()
local os_name="$OS"
if [[ -z "$os_name" ]]; then
case "$(uname -s)" in
Darwin*) os_name="darwin" ;;
*) os_name="linux" ;;
esac
fi
# Determine shell config files
if [[ -n "$ZSH_VERSION" ]] || [[ "$SHELL" == *"zsh"* ]]; then
candidates+=("$HOME/.zshrc")
fi
if [[ -n "$BASH_VERSION" ]] || [[ "$SHELL" == *"bash"* ]]; then
if [[ "$os_name" == "darwin" ]]; then
candidates+=("$HOME/.bash_profile")
else
candidates+=("$HOME/.bashrc")
fi
fi
if [[ "$SHELL" == *"fish"* ]]; then
candidates+=("$HOME/.config/fish/config.fish")
fi
for file in "${candidates[@]}"; do
if [[ -f "$file" ]] && grep -q "$install_dir" "$file" 2>/dev/null; then
local tmp
tmp=$(mktemp)
# Remove the comment marker and PATH export line we added
grep -v "Drip client" "$file" | grep -v "$install_dir" > "$tmp" || true
mv "$tmp" "$file"
fi
done
}
remove_config_dirs() {
local removed=false
local dirs=("$HOME/.drip" "$HOME/.config/drip")
echo ""
prompt_input "$(msg remove_config_prompt) [y/N]: " remove_choice
if [[ ! "$remove_choice" =~ ^[Yy]$ ]]; then
return
fi
for dir in "${dirs[@]}"; do
if [[ -d "$dir" ]]; then
rm -rf "$dir"
removed=true
fi
done
if [[ "$removed" == true ]]; then
print_success "$(msg config_removed)"
fi
}
uninstall_client() {
if ! command -v drip &> /dev/null; then
print_warning "$(msg uninstall_not_found)"
return
fi
local current_path
current_path=$(command -v drip)
prompt_input "$(msg uninstall_prompt) [y/N]: " confirm_uninstall
if [[ ! "$confirm_uninstall" =~ ^[Yy]$ ]]; then
return
fi
print_step "$(msg uninstalling)"
if [[ -w "$current_path" ]]; then
rm -f "$current_path" || true
else
sudo rm -f "$current_path" || true
fi
print_success "$(msg uninstall_done)"
local install_dir
install_dir=$(dirname "$current_path")
print_step "$(msg path_cleanup)"
cleanup_path_entries "$install_dir"
print_success "$(msg path_cleanup_done)"
remove_config_dirs
}
# ============================================================================
# Main
# ============================================================================
main() {
if [[ "$1" == "--uninstall" || "$1" == "uninstall" ]]; then
UNINSTALL_MODE=true
fi
clear
print_banner
if [[ "$SKIP_LANG_PROMPT" == "true" ]]; then
# Respect pre-set LANG_CODE when skipping the language prompt
LANG_CODE="${LANG_CODE:-en}"
else
select_language
fi
echo -e "${BOLD}────────────────────────────────────────────${NC}"
if [[ "$UNINSTALL_MODE" == true ]]; then
uninstall_client
exit 0
fi
check_os
check_arch
check_dependencies
check_existing_install
echo ""
download_binary
select_install_dir
install_binary
ensure_command_access
update_path
verify_installation
# Skip configuration for updates
if [[ "$IS_UPDATE" != true ]]; then
configure_client
test_connection
else
echo ""
local new_version=$(get_version_from_binary "$INSTALL_DIR/$BINARY_NAME")
print_panel "$(msg update_ok)"
print_info "Version: $new_version"
echo ""
return
fi
show_completion
}
# Run
main "$@"