You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

295 lines
7.8 KiB

#!/bin/bash
set -e
# Colors for output / 输出颜色
RED='\033[0;31m'
GREEN='\033[0;32m'
BLUE='\033[0;36m'
YELLOW='\033[0;33m'
NC='\033[0m' # No Color / 无颜色
# Messages / 消息
EN_MESSAGES=(
"Starting installation..."
"Detected OS:"
"Downloading latest release..."
"URL:"
"Installing binary..."
"Cleaning up..."
"Installation completed successfully!"
"You can now use 'sudo %s' from your terminal"
"Failed to download binary from:"
"Failed to download the binary"
"curl is required but not installed. Please install curl first."
"sudo is required but not installed. Please install sudo first."
"Unsupported operating system"
"Unsupported architecture:"
"Checking for running Cursor instances..."
"Found running Cursor processes. Attempting to close them..."
"Successfully closed all Cursor instances"
"Failed to close Cursor instances. Please close them manually"
"Backing up storage.json..."
"Backup created at:"
"This script requires root privileges. Requesting sudo access..."
)
CN_MESSAGES=(
"开始安装..."
"检测到操作系统:"
"正在下载最新版本..."
"下载地址:"
"正在安装程序..."
"正在清理..."
"安装成功完成!"
"现在可以在终端中使用 'sudo %s' 了"
"从以下地址下载二进制文件失败:"
"下载二进制文件失败"
"需要 curl 但未安装。请先安装 curl。"
"需要 sudo 但未安装。请先安装 sudo。"
"不支持的操作系统"
"不支持的架构:"
"正在检查运行中的Cursor进程..."
"发现正在运行的Cursor进程,尝试关闭..."
"成功关闭所有Cursor实例"
"无法关闭Cursor实例,请手动关闭"
"正在备份storage.json..."
"备份已创建于:"
"此脚本需要root权限。正在请求sudo访问..."
)
# Detect system language / 检测系统语言
detect_language() {
if [[ $(locale | grep "LANG=zh_CN") ]]; then
echo "cn"
else
echo "en"
fi
}
# Get message based on language / 根据语言获取消息
get_message() {
local index=$1
local lang=$(detect_language)
if [[ "$lang" == "cn" ]]; then
echo "${CN_MESSAGES[$index]}"
else
echo "${EN_MESSAGES[$index]}"
fi
}
# Print with color / 带颜色打印
print_status() {
echo -e "${BLUE}[*]${NC} $1"
}
print_success() {
echo -e "${GREEN}[✓]${NC} $1"
}
print_warning() {
echo -e "${YELLOW}[!]${NC} $1"
}
print_error() {
echo -e "${RED}[✗]${NC} $1"
exit 1
}
# Check and request root privileges / 检查并请求root权限
check_root() {
if [ "$EUID" -ne 0 ]; then
print_status "$(get_message 20)"
if command -v sudo >/dev/null 2>&1; then
exec sudo bash "$0" "$@"
else
print_error "$(get_message 11)"
fi
fi
}
# Close Cursor instances / 关闭Cursor实例
close_cursor_instances() {
print_status "$(get_message 14)"
if pgrep -x "Cursor" >/dev/null; then
print_status "$(get_message 15)"
if pkill -x "Cursor" 2>/dev/null; then
sleep 2
print_success "$(get_message 16)"
else
print_error "$(get_message 17)"
fi
fi
}
# Backup storage.json / 备份storage.json
backup_storage_json() {
print_status "$(get_message 18)"
local storage_path
if [ "$(uname)" == "Darwin" ]; then
storage_path="$HOME/Library/Application Support/Cursor/User/globalStorage/storage.json"
else
storage_path="$HOME/.config/Cursor/User/globalStorage/storage.json"
fi
if [ -f "$storage_path" ]; then
cp "$storage_path" "${storage_path}.backup"
print_success "$(get_message 19) ${storage_path}.backup"
fi
}
# Detect OS / 检测操作系统
detect_os() {
if [[ "$OSTYPE" == "darwin"* ]]; then
echo "macos"
elif [[ "$OSTYPE" == "linux-gnu"* ]]; then
echo "linux"
else
print_error "$(get_message 12)"
fi
}
# Get latest release version from GitHub / 从GitHub获取最新版本
get_latest_version() {
local repo="yuaotian/go-cursor-help"
curl -s "https://api.github.com/repos/${repo}/releases/latest" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/'
}
# Get the binary name based on OS and architecture / 根据操作系统和架构获取二进制文件名
get_binary_name() {
OS=$(detect_os)
ARCH=$(uname -m)
VERSION=$(get_latest_version)
case "$ARCH" in
x86_64)
echo "cursor_id_modifier_${VERSION}_${OS}_amd64"
;;
aarch64|arm64)
echo "cursor_id_modifier_${VERSION}_${OS}_arm64"
;;
*)
print_error "$(get_message 13) $ARCH"
;;
esac
}
# Add download progress display function
download_with_progress() {
local url="$1"
local output_file="$2"
curl -L -f --progress-bar "$url" -o "$output_file"
return $?
}
# Optimize installation function
install_binary() {
OS=$(detect_os)
VERSION=$(get_latest_version)
VERSION_WITHOUT_V=${VERSION#v} # Remove 'v' from version number
BINARY_NAME="cursor_id_modifier_${VERSION_WITHOUT_V}_${OS}_$(get_arch)"
REPO="yuaotian/go-cursor-help"
DOWNLOAD_URL="https://github.com/${REPO}/releases/download/${VERSION}/${BINARY_NAME}"
TMP_DIR=$(mktemp -d)
FINAL_BINARY_NAME="cursor-id-modifier"
print_status "$(get_message 2)"
print_status "$(get_message 3) ${DOWNLOAD_URL}"
if ! download_with_progress "$DOWNLOAD_URL" "$TMP_DIR/$BINARY_NAME"; then
rm -rf "$TMP_DIR"
print_error "$(get_message 8) $DOWNLOAD_URL"
fi
if [ ! -f "$TMP_DIR/$BINARY_NAME" ]; then
rm -rf "$TMP_DIR"
print_error "$(get_message 9)"
fi
print_status "$(get_message 4)"
INSTALL_DIR="/usr/local/bin"
# Create directory if it doesn't exist
mkdir -p "$INSTALL_DIR"
# Move binary to installation directory
if ! mv "$TMP_DIR/$BINARY_NAME" "$INSTALL_DIR/$FINAL_BINARY_NAME"; then
rm -rf "$TMP_DIR"
print_error "Failed to move binary to installation directory"
fi
if ! chmod +x "$INSTALL_DIR/$FINAL_BINARY_NAME"; then
rm -rf "$TMP_DIR"
print_error "Failed to set executable permissions"
fi
# Cleanup
print_status "$(get_message 5)"
rm -rf "$TMP_DIR"
print_success "$(get_message 6)"
printf "${GREEN}[✓]${NC} $(get_message 7)\n" "$FINAL_BINARY_NAME"
# Try to run the program directly
if [ -x "$INSTALL_DIR/$FINAL_BINARY_NAME" ]; then
"$INSTALL_DIR/$FINAL_BINARY_NAME" &
else
print_warning "Failed to start cursor-id-modifier"
fi
}
# Optimize architecture detection function
get_arch() {
case "$(uname -m)" in
x86_64)
echo "amd64"
;;
aarch64|arm64)
echo "arm64"
;;
*)
print_error "$(get_message 13) $(uname -m)"
;;
esac
}
# Check for required tools / 检查必需工具
check_requirements() {
if ! command -v curl >/dev/null 2>&1; then
print_error "$(get_message 10)"
fi
if ! command -v sudo >/dev/null 2>&1; then
print_error "$(get_message 11)"
fi
}
# Main installation process / 主安装过程
main() {
print_status "$(get_message 0)"
# Check root privileges / 检查root权限
check_root "$@"
# Check required tools / 检查必需工具
check_requirements
# Close Cursor instances / 关闭Cursor实例
close_cursor_instances
# Backup storage.json / 备份storage.json
backup_storage_json
OS=$(detect_os)
print_status "$(get_message 1) $OS"
# Install the binary / 安装二进制文件
install_binary
}
# Run main function / 运行主函数
main "$@"