Browse Source
refactor: Remove install.sh and enhance README.md with updated installation instructions
refactor: Remove install.sh and enhance README.md with updated installation instructions
- Deleted the `install.sh` script to streamline the installation process and reduce complexity. - Updated the `README.md` to reflect the new installation method, emphasizing the recommended automatic installation approach. - Improved clarity in installation instructions for both Linux/macOS and Windows, ensuring users have clear guidance on how to install the tool. - Added details about the automatic installation script's features, including privilege requests and configuration backups. - Enhanced the manual installation section with step-by-step instructions for users who prefer that method. These changes collectively improve the documentation and user experience during the installation process.pull/33/head
6 changed files with 674 additions and 323 deletions
-
82README.md
-
255install.sh
-
75scripts/build_all.bat
-
116scripts/build_all.sh
-
216scripts/install.ps1
-
251scripts/install.sh
@ -1,255 +0,0 @@ |
|||||
#!/bin/bash |
|
||||
|
|
||||
# Version / 版本号 |
|
||||
VERSION="v2.0.0" |
|
||||
|
|
||||
# Configuration / 配置 |
|
||||
KEEP_BINARY=false |
|
||||
DOWNLOAD_DIR="/tmp" |
|
||||
INSTALL_DIR="/usr/local/bin" |
|
||||
AUTO_SUDO=false |
|
||||
|
|
||||
# Colors / 颜色 |
|
||||
RED='\033[31m' |
|
||||
GREEN='\033[32m' |
|
||||
YELLOW='\033[33m' |
|
||||
BLUE='\033[36m' |
|
||||
BOLD='\033[1m' |
|
||||
NC='\033[0m' |
|
||||
|
|
||||
# Separator / 分隔线 |
|
||||
SEPARATOR="${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}" |
|
||||
|
|
||||
# Bilingual message functions / 双语消息函数 |
|
||||
error() { |
|
||||
echo -e "\n${SEPARATOR}" |
|
||||
echo -e "${RED}${BOLD}❌ Error:${NC} $1" |
|
||||
echo -e "${RED}${BOLD}❌ 错误:${NC}$2" |
|
||||
echo -e "${SEPARATOR}\n" |
|
||||
exit 1 |
|
||||
} |
|
||||
|
|
||||
info() { |
|
||||
echo -e "\n${BLUE}${BOLD}ℹ️ [EN]:${NC} $1" |
|
||||
echo -e "${BLUE}${BOLD}ℹ️ [中文]:${NC} $2\n" |
|
||||
} |
|
||||
|
|
||||
success() { |
|
||||
echo -e "\n${SEPARATOR}" |
|
||||
echo -e "${GREEN}${BOLD}✅ [EN]:${NC} $1" |
|
||||
echo -e "${GREEN}${BOLD}✅ [中文]:${NC} $2" |
|
||||
echo -e "${SEPARATOR}\n" |
|
||||
} |
|
||||
|
|
||||
warning() { |
|
||||
echo -e "\n${YELLOW}${BOLD}⚠️ [EN]:${NC} $1" |
|
||||
echo -e "${YELLOW}${BOLD}⚠️ [中文]:${NC} $2\n" |
|
||||
} |
|
||||
|
|
||||
# System detection / 系统检测 |
|
||||
detect_platform() { |
|
||||
OS=$(uname -s | tr '[:upper:]' '[:lower:]') |
|
||||
ARCH=$(uname -m) |
|
||||
|
|
||||
case "$OS" in |
|
||||
linux*) |
|
||||
case "$ARCH" in |
|
||||
x86_64) BINARY_NAME="cursor_id_modifier_${VERSION}_linux_amd64" ;; |
|
||||
*) error "Unsupported Linux architecture: $ARCH" "不支持的Linux架构:$ARCH" ;; |
|
||||
esac |
|
||||
;; |
|
||||
darwin*) |
|
||||
case "$ARCH" in |
|
||||
x86_64) BINARY_NAME="cursor_id_modifier_${VERSION}_darwin_amd64_intel" ;; |
|
||||
arm64) BINARY_NAME="cursor_id_modifier_${VERSION}_darwin_arm64_m1" ;; |
|
||||
*) error "Unsupported macOS architecture: $ARCH" "不支持的macOS架构:$ARCH" ;; |
|
||||
esac |
|
||||
;; |
|
||||
msys*|mingw*|cygwin*) |
|
||||
case "$ARCH" in |
|
||||
x86_64) BINARY_NAME="cursor_id_modifier_${VERSION}_windows_amd64.exe" ;; |
|
||||
*) error "Unsupported Windows architecture: $ARCH" "不支持的Windows架构:$ARCH" ;; |
|
||||
esac |
|
||||
;; |
|
||||
*) |
|
||||
error "Unsupported operating system: $OS" "不支持的操作系统:$OS" |
|
||||
;; |
|
||||
esac |
|
||||
} |
|
||||
|
|
||||
# System checks / 系统检查 |
|
||||
check_requirements() { |
|
||||
info "Checking system requirements..." "正在检查系统要求..." |
|
||||
|
|
||||
# Check network connectivity / 检查网络连接 |
|
||||
if ! ping -c 1 github.com >/dev/null 2>&1; then |
|
||||
error "No network connection to GitHub" "无法连接到 GitHub" |
|
||||
fi |
|
||||
|
|
||||
# Check curl / 检查curl |
|
||||
if ! command -v curl >/dev/null 2>&1; then |
|
||||
error "curl is required. Please install curl first." \ |
|
||||
"需要安装 curl。请先安装 curl 后再运行此脚本。" |
|
||||
fi |
|
||||
} |
|
||||
|
|
||||
# Privilege check / 权限检查 |
|
||||
check_privileges() { |
|
||||
if [ "$EUID" -ne 0 ]; then |
|
||||
if [ "$AUTO_SUDO" = "true" ]; then |
|
||||
if command -v sudo >/dev/null 2>&1; then |
|
||||
info "Re-running with sudo..." "使用 sudo 重新运行..." |
|
||||
exec sudo bash "$0" "$@" |
|
||||
else |
|
||||
error "This script must be run as root. Please use sudo." \ |
|
||||
"此脚本必须以 root 身份运行。请使用 sudo。" |
|
||||
fi |
|
||||
else |
|
||||
error "This script must be run as root. Please use sudo." \ |
|
||||
"此脚本必须以 root 身份运行。请使用 sudo。" |
|
||||
fi |
|
||||
fi |
|
||||
} |
|
||||
|
|
||||
# Binary verification / 二进制验证 |
|
||||
verify_binary() { |
|
||||
info "Verifying binary..." "正在验证二进制文件..." |
|
||||
|
|
||||
# Check file existence / 检查文件是否存在 |
|
||||
if [ ! -f "$DOWNLOAD_PATH" ]; then |
|
||||
error "Binary file download failed or does not exist" \ |
|
||||
"二进制文件下载失败或不存在" |
|
||||
fi |
|
||||
|
|
||||
# Check executable format / 检查可执行格式 |
|
||||
if ! file "$DOWNLOAD_PATH" | grep -q "executable"; then |
|
||||
error "Downloaded file is not an executable" \ |
|
||||
"下载的文件不是可执行文件" |
|
||||
fi |
|
||||
|
|
||||
# Check file size / 检查文件大小 |
|
||||
local size=$(wc -c < "$DOWNLOAD_PATH") |
|
||||
if [ "$size" -lt 1000000 ]; then # At least 1MB / 至少1MB |
|
||||
error "Downloaded file size is abnormal" \ |
|
||||
"下载的文件大小异常" |
|
||||
fi |
|
||||
|
|
||||
# Set executable permissions / 设置可执行权限 |
|
||||
info "Setting executable permissions..." "正在设置可执行权限..." |
|
||||
if ! chmod +x "$DOWNLOAD_PATH"; then |
|
||||
error "Failed to set executable permissions" "无法设置可执行权限" |
|
||||
fi |
|
||||
} |
|
||||
|
|
||||
# Cleanup functions / 清理函数 |
|
||||
cleanup_old_version() { |
|
||||
if [ -f "$INSTALL_DIR/cursor-id-modifier" ]; then |
|
||||
info "Removing old version..." "正在删除旧版..." |
|
||||
rm -f "$INSTALL_DIR/cursor-id-modifier" || \ |
|
||||
error "Failed to remove old version" "删除旧版本失败" |
|
||||
fi |
|
||||
} |
|
||||
|
|
||||
cleanup_temp_files() { |
|
||||
if [ "$KEEP_BINARY" = "false" ]; then |
|
||||
rm -f "$DOWNLOAD_PATH" |
|
||||
rm -f "$INSTALL_DIR/cursor-id-modifier-wrapper" |
|
||||
fi |
|
||||
} |
|
||||
|
|
||||
# Parse arguments / 解析参数 |
|
||||
parse_args() { |
|
||||
while [[ $# -gt 0 ]]; do |
|
||||
case $1 in |
|
||||
--auto-sudo) |
|
||||
AUTO_SUDO=true |
|
||||
shift |
|
||||
;; |
|
||||
--keep-binary) |
|
||||
KEEP_BINARY=true |
|
||||
shift |
|
||||
;; |
|
||||
--download-dir=*) |
|
||||
DOWNLOAD_DIR="${1#*=}" |
|
||||
shift |
|
||||
;; |
|
||||
*) |
|
||||
shift |
|
||||
;; |
|
||||
esac |
|
||||
done |
|
||||
} |
|
||||
|
|
||||
# Print banner / 打印横幅 |
|
||||
print_banner() { |
|
||||
echo -e "\n${BLUE}${BOLD}" |
|
||||
echo " ██████╗██╗ ██╗██████╗ ███████╗ ██████╗ ██████╗" |
|
||||
echo " ██╔════╝██║ ██║██╔══██╗██╔════╝█╔═══██╗██╔══██╗" |
|
||||
echo " ██║ ██║ ██║██████╔╝███████╗██║ ██║██████╔╝" |
|
||||
echo " ██║ ██║ ██║██╔══██╗╚════██ ██║ ██║██╔══██╗" |
|
||||
echo " ╚██████╗╚██████╔╝██║ ██║███████║╚██████╔╝██║ ██║" |
|
||||
echo " ╚════╝ ╚═════╝ ╚═╝ ╚═╝╚══════╝ ╚════╝ ╚═╝ ╚═╝" |
|
||||
echo -e "${NC}" |
|
||||
echo -e "${YELLOW}${BOLD} >> Cursor ID Modifier ${VERSION} <<${NC}" |
|
||||
echo -e "${BLUE}${BOLD} [ By Pancake Fruit Rolled Shark Chili ]${NC}\n" |
|
||||
} |
|
||||
|
|
||||
# Main installation process / 主安装流程 |
|
||||
main() { |
|
||||
check_privileges "$@" |
|
||||
|
|
||||
print_banner |
|
||||
|
|
||||
info "Starting installation of cursor-id-modifier ${VERSION}..." \ |
|
||||
"开始安装 cursor-id-modifier ${VERSION}..." |
|
||||
|
|
||||
detect_platform |
|
||||
check_requirements |
|
||||
|
|
||||
# Create installation directory / 创建安装目录 |
|
||||
mkdir -p "$INSTALL_DIR" 2>/dev/null || \ |
|
||||
error "Failed to create installation directory" "无法创建安装目录" |
|
||||
|
|
||||
# Download binary / 下载二进制文件 |
|
||||
info "Downloading cursor-id-modifier ($OS-$ARCH)..." \ |
|
||||
"正在下载 cursor-id-modifier ($OS-$ARCH)..." |
|
||||
|
|
||||
DOWNLOAD_URL="https://github.com/yuaotian/go-cursor-help/raw/refs/heads/master/bin/$BINARY_NAME" |
|
||||
DOWNLOAD_PATH="$DOWNLOAD_DIR/$BINARY_NAME" |
|
||||
|
|
||||
if ! curl -L --progress-bar "$DOWNLOAD_URL" -o "$DOWNLOAD_PATH"; then |
|
||||
error "Failed to download binary" "下载二进制文件失败" |
|
||||
fi |
|
||||
|
|
||||
success "Download completed" "下载完成" |
|
||||
|
|
||||
verify_binary |
|
||||
cleanup_old_version |
|
||||
|
|
||||
# Install binary / 安装二进制文件 |
|
||||
info "Installing binary..." "正在安装二进制文件..." |
|
||||
if ! cp "$DOWNLOAD_PATH" "$INSTALL_DIR/cursor-id-modifier"; then |
|
||||
error "Failed to install binary" "安装二进制文件失败" |
|
||||
fi |
|
||||
|
|
||||
# Create wrapper script / 创建包装脚本 |
|
||||
cat > "$INSTALL_DIR/cursor-id-modifier-wrapper" << 'EOF' |
|
||||
#!/bin/bash |
|
||||
if [ "$(uname -s)" = "Darwin" ]; then |
|
||||
sudo /usr/local/bin/cursor-id-modifier "$@" |
|
||||
else |
|
||||
sudo /usr/local/bin/cursor-id-modifier "$@" |
|
||||
fi |
|
||||
EOF |
|
||||
chmod +x "$INSTALL_DIR/cursor-id-modifier-wrapper" |
|
||||
|
|
||||
# Cleanup / 清理 |
|
||||
cleanup_temp_files |
|
||||
|
|
||||
success "Installation successful! Run 'cursor-id-modifier-wrapper' from anywhere." \ |
|
||||
"安装成功!现在可以在任何位置运行 'cursor-id-modifier-wrapper'。" |
|
||||
} |
|
||||
|
|
||||
# Start installation / 开始安装 |
|
||||
parse_args "$@" |
|
||||
main "$@" |
|
@ -0,0 +1,216 @@ |
|||||
|
# Auto-elevate to admin rights if not already running as admin |
||||
|
if (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) { |
||||
|
Write-Host "Requesting administrator privileges..." |
||||
|
Start-Process powershell.exe "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`"" -Verb RunAs |
||||
|
Exit |
||||
|
} |
||||
|
|
||||
|
# Set TLS to 1.2 / 设置 TLS 为 1.2 |
||||
|
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 |
||||
|
|
||||
|
# Colors for output / 输出颜色 |
||||
|
$Red = "`e[31m" |
||||
|
$Green = "`e[32m" |
||||
|
$Blue = "`e[36m" |
||||
|
$Yellow = "`e[33m" |
||||
|
$Reset = "`e[0m" |
||||
|
|
||||
|
# Messages / 消息 |
||||
|
$EN_MESSAGES = @( |
||||
|
"Starting installation...", |
||||
|
"Detected architecture:", |
||||
|
"Only 64-bit Windows is supported", |
||||
|
"Latest version:", |
||||
|
"Creating installation directory...", |
||||
|
"Downloading latest release from:", |
||||
|
"Failed to download binary:", |
||||
|
"Downloaded file not found", |
||||
|
"Installing binary...", |
||||
|
"Failed to install binary:", |
||||
|
"Adding to PATH...", |
||||
|
"Cleaning up...", |
||||
|
"Installation completed successfully!", |
||||
|
"You can now use 'cursor-id-modifier' from any terminal (you may need to restart your terminal first)", |
||||
|
"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:" |
||||
|
) |
||||
|
|
||||
|
$CN_MESSAGES = @( |
||||
|
"开始安装...", |
||||
|
"检测到架构:", |
||||
|
"仅支持64位Windows系统", |
||||
|
"最新版本:", |
||||
|
"正在创建安装目录...", |
||||
|
"正在从以下地址下载最新版本:", |
||||
|
"下载二进制文件失败:", |
||||
|
"未找到下载的文件", |
||||
|
"正在安装程序...", |
||||
|
"安装二进制文件失败:", |
||||
|
"正在添加到PATH...", |
||||
|
"正在清理...", |
||||
|
"安装成功完成!", |
||||
|
"现在可以在任何终端中使用 'cursor-id-modifier' 了(可能需要重启终端)", |
||||
|
"正在检查运行中的Cursor进程...", |
||||
|
"发现正在运行的Cursor进程,尝试关闭...", |
||||
|
"成功关闭所有Cursor实例", |
||||
|
"无法关闭Cursor实例,请手动关闭", |
||||
|
"正在备份storage.json...", |
||||
|
"备份已创建于:" |
||||
|
) |
||||
|
|
||||
|
# Detect system language / 检测系统语言 |
||||
|
function Get-SystemLanguage { |
||||
|
if ((Get-Culture).Name -like "zh-CN") { |
||||
|
return "cn" |
||||
|
} |
||||
|
return "en" |
||||
|
} |
||||
|
|
||||
|
# Get message based on language / 根据语言获取消息 |
||||
|
function Get-Message($Index) { |
||||
|
$lang = Get-SystemLanguage |
||||
|
if ($lang -eq "cn") { |
||||
|
return $CN_MESSAGES[$Index] |
||||
|
} |
||||
|
return $EN_MESSAGES[$Index] |
||||
|
} |
||||
|
|
||||
|
# Functions for colored output / 彩色输出函数 |
||||
|
function Write-Status($Message) { |
||||
|
Write-Host "${Blue}[*]${Reset} $Message" |
||||
|
} |
||||
|
|
||||
|
function Write-Success($Message) { |
||||
|
Write-Host "${Green}[✓]${Reset} $Message" |
||||
|
} |
||||
|
|
||||
|
function Write-Warning($Message) { |
||||
|
Write-Host "${Yellow}[!]${Reset} $Message" |
||||
|
} |
||||
|
|
||||
|
function Write-Error($Message) { |
||||
|
Write-Host "${Red}[✗]${Reset} $Message" |
||||
|
Exit 1 |
||||
|
} |
||||
|
|
||||
|
# Close Cursor instances / 关闭Cursor实例 |
||||
|
function Close-CursorInstances { |
||||
|
Write-Status (Get-Message 14) |
||||
|
$cursorProcesses = Get-Process "Cursor" -ErrorAction SilentlyContinue |
||||
|
|
||||
|
if ($cursorProcesses) { |
||||
|
Write-Status (Get-Message 15) |
||||
|
try { |
||||
|
$cursorProcesses | ForEach-Object { $_.CloseMainWindow() | Out-Null } |
||||
|
Start-Sleep -Seconds 2 |
||||
|
$cursorProcesses | Where-Object { !$_.HasExited } | Stop-Process -Force |
||||
|
Write-Success (Get-Message 16) |
||||
|
} catch { |
||||
|
Write-Error (Get-Message 17) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
# Backup storage.json / 备份storage.json |
||||
|
function Backup-StorageJson { |
||||
|
Write-Status (Get-Message 18) |
||||
|
$storageJsonPath = "$env:APPDATA\Cursor\User\globalStorage\storage.json" |
||||
|
if (Test-Path $storageJsonPath) { |
||||
|
$backupPath = "$storageJsonPath.backup" |
||||
|
Copy-Item -Path $storageJsonPath -Destination $backupPath -Force |
||||
|
Write-Success "$(Get-Message 19) $backupPath" |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
# Get latest release version from GitHub / 从GitHub获取最新版本 |
||||
|
function Get-LatestVersion { |
||||
|
$repo = "yuaotian/go-cursor-help" |
||||
|
$release = Invoke-RestMethod -Uri "https://api.github.com/repos/$repo/releases/latest" |
||||
|
return $release.tag_name |
||||
|
} |
||||
|
|
||||
|
# Main installation process / 主安装过程 |
||||
|
Write-Status (Get-Message 0) |
||||
|
|
||||
|
# Close any running Cursor instances |
||||
|
Close-CursorInstances |
||||
|
|
||||
|
# Backup storage.json |
||||
|
Backup-StorageJson |
||||
|
|
||||
|
# Get system architecture / 获取系统架构 |
||||
|
$arch = if ([Environment]::Is64BitOperatingSystem) { "amd64" } else { "386" } |
||||
|
Write-Status "$(Get-Message 1) $arch" |
||||
|
|
||||
|
if ($arch -ne "amd64") { |
||||
|
Write-Error (Get-Message 2) |
||||
|
} |
||||
|
|
||||
|
# Get latest version / 获取最新版本 |
||||
|
$version = Get-LatestVersion |
||||
|
Write-Status "$(Get-Message 3) $version" |
||||
|
|
||||
|
# Set up paths / 设置路径 |
||||
|
$installDir = "$env:ProgramFiles\cursor-id-modifier" |
||||
|
$binaryName = "cursor_id_modifier_${version}_windows_amd64.exe" |
||||
|
$downloadUrl = "https://github.com/yuaotian/go-cursor-help/releases/download/$version/$binaryName" |
||||
|
$tempFile = "$env:TEMP\$binaryName" |
||||
|
|
||||
|
# Create installation directory / 创建安装目录 |
||||
|
Write-Status (Get-Message 4) |
||||
|
if (-not (Test-Path $installDir)) { |
||||
|
New-Item -ItemType Directory -Path $installDir -Force | Out-Null |
||||
|
} |
||||
|
|
||||
|
# Download binary / 下载二进制文件 |
||||
|
Write-Status "$(Get-Message 5) $downloadUrl" |
||||
|
try { |
||||
|
Invoke-WebRequest -Uri $downloadUrl -OutFile $tempFile |
||||
|
} catch { |
||||
|
Write-Error "$(Get-Message 6) $_" |
||||
|
} |
||||
|
|
||||
|
# Verify download / 验证下载 |
||||
|
if (-not (Test-Path $tempFile)) { |
||||
|
Write-Error (Get-Message 7) |
||||
|
} |
||||
|
|
||||
|
# Install binary / 安装二进制文件 |
||||
|
Write-Status (Get-Message 8) |
||||
|
try { |
||||
|
Move-Item -Force $tempFile "$installDir\cursor-id-modifier.exe" |
||||
|
} catch { |
||||
|
Write-Error "$(Get-Message 9) $_" |
||||
|
} |
||||
|
|
||||
|
# Add to PATH if not already present / 如果尚未添加则添加到PATH |
||||
|
$userPath = [Environment]::GetEnvironmentVariable("Path", "User") |
||||
|
if ($userPath -notlike "*$installDir*") { |
||||
|
Write-Status (Get-Message 10) |
||||
|
[Environment]::SetEnvironmentVariable( |
||||
|
"Path", |
||||
|
"$userPath;$installDir", |
||||
|
"User" |
||||
|
) |
||||
|
} |
||||
|
|
||||
|
# Create shortcut in Start Menu / 在开始菜单创建快捷方式 |
||||
|
$startMenuPath = "$env:ProgramData\Microsoft\Windows\Start Menu\Programs\cursor-id-modifier.lnk" |
||||
|
$shell = New-Object -ComObject WScript.Shell |
||||
|
$shortcut = $shell.CreateShortcut($startMenuPath) |
||||
|
$shortcut.TargetPath = "$installDir\cursor-id-modifier.exe" |
||||
|
$shortcut.Save() |
||||
|
|
||||
|
# Cleanup / 清理 |
||||
|
Write-Status (Get-Message 11) |
||||
|
if (Test-Path $tempFile) { |
||||
|
Remove-Item -Force $tempFile |
||||
|
} |
||||
|
|
||||
|
Write-Success (Get-Message 12) |
||||
|
Write-Success (Get-Message 13) |
||||
|
Write-Host "" |
@ -0,0 +1,251 @@ |
|||||
|
#!/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 |
||||
|
} |
||||
|
|
||||
|
# Install the binary / 安装二进制文件 |
||||
|
install_binary() { |
||||
|
OS=$(detect_os) |
||||
|
BINARY_NAME=$(get_binary_name) |
||||
|
REPO="yuaotian/go-cursor-help" |
||||
|
VERSION=$(get_latest_version) |
||||
|
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 ! curl -L -f "$DOWNLOAD_URL" -o "$TMP_DIR/$BINARY_NAME"; then |
||||
|
print_error "$(get_message 8) $DOWNLOAD_URL" |
||||
|
fi |
||||
|
|
||||
|
if [ ! -f "$TMP_DIR/$BINARY_NAME" ]; then |
||||
|
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 / 移动二进制文件到安装目录 |
||||
|
mv "$TMP_DIR/$BINARY_NAME" "$INSTALL_DIR/$FINAL_BINARY_NAME" |
||||
|
chmod +x "$INSTALL_DIR/$FINAL_BINARY_NAME" |
||||
|
|
||||
|
# 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" |
||||
|
} |
||||
|
|
||||
|
# 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 "$@" |
||||
|
|
||||
|
# Close Cursor instances / 关闭Cursor实例 |
||||
|
close_cursor_instances |
||||
|
|
||||
|
# Backup storage.json / 备份storage.json |
||||
|
backup_storage_json |
||||
|
|
||||
|
OS=$(detect_os) |
||||
|
print_status "$(get_message 1) $OS" |
||||
|
|
||||
|
check_requirements |
||||
|
install_binary |
||||
|
} |
||||
|
|
||||
|
# Run main function / 运行主函数 |
||||
|
main "$@" |
Write
Preview
Loading…
Cancel
Save
Reference in new issue