mirror of
https://github.com/yuaotian/go-cursor-help.git
synced 2026-04-28 05:12:49 +00:00
chore: Refactor build and installation scripts; update configuration and release process
- Enhanced build scripts for improved parallel execution and optimization flags. - Updated installation scripts for better user experience and error handling. - Modified .gitignore to include new build artifacts and IDE configurations. - Updated .goreleaser.yml for better release management and platform support. - Removed deprecated main.go file and adjusted README for clarity on installation and usage. - Added support for multiple architectures in build process, including 32-bit and 64-bit for Windows, macOS, and Linux. These changes streamline the development workflow and enhance the overall usability of the Cursor ID Modifier tool.
This commit is contained in:
@@ -1,128 +1,74 @@
|
||||
@echo off
|
||||
setlocal EnableDelayedExpansion
|
||||
|
||||
:: Build optimization flags
|
||||
set "OPTIMIZATION_FLAGS=-trimpath -ldflags=\"-s -w\""
|
||||
set "BUILD_JOBS=4"
|
||||
|
||||
:: Messages / 消息
|
||||
set "EN_MESSAGES[0]=Starting build process for version"
|
||||
set "EN_MESSAGES[1]=Using optimization flags:"
|
||||
set "EN_MESSAGES[2]=Cleaning old builds..."
|
||||
set "EN_MESSAGES[3]=Cleanup completed"
|
||||
set "EN_MESSAGES[4]=bin directory does not exist, no cleanup needed"
|
||||
set "EN_MESSAGES[5]=Starting builds for all platforms..."
|
||||
set "EN_MESSAGES[6]=Building for"
|
||||
set "EN_MESSAGES[7]=Build successful:"
|
||||
set "EN_MESSAGES[8]=Build failed for"
|
||||
set "EN_MESSAGES[9]=All builds completed! Total time:"
|
||||
set "EN_MESSAGES[10]=seconds"
|
||||
set "EN_MESSAGES[4]=Starting builds for all platforms..."
|
||||
set "EN_MESSAGES[5]=Building for"
|
||||
set "EN_MESSAGES[6]=Build successful:"
|
||||
set "EN_MESSAGES[7]=All builds completed!"
|
||||
|
||||
set "CN_MESSAGES[0]=开始构建版本"
|
||||
set "CN_MESSAGES[1]=使用优化标志:"
|
||||
set "CN_MESSAGES[2]=正在清理旧的构建文件..."
|
||||
set "CN_MESSAGES[3]=清理完成"
|
||||
set "CN_MESSAGES[4]=bin 目录不存在,无需清理"
|
||||
set "CN_MESSAGES[5]=开始编译所有平台..."
|
||||
set "CN_MESSAGES[6]=正在构建"
|
||||
set "CN_MESSAGES[7]=构建成功:"
|
||||
set "CN_MESSAGES[8]=构建失败:"
|
||||
set "CN_MESSAGES[9]=所有构建完成!总耗时:"
|
||||
set "CN_MESSAGES[10]=秒"
|
||||
|
||||
:: 设置版本信息 / Set version
|
||||
set VERSION=2.0.0
|
||||
|
||||
:: 设置颜色代码 / Set color codes
|
||||
:: Colors
|
||||
set "GREEN=[32m"
|
||||
set "RED=[31m"
|
||||
set "YELLOW=[33m"
|
||||
set "RESET=[0m"
|
||||
|
||||
:: 设置编译优化标志 / Set build optimization flags
|
||||
set "LDFLAGS=-s -w"
|
||||
set "BUILDMODE=pie"
|
||||
set "GCFLAGS=-N -l"
|
||||
|
||||
:: 设置 CGO / Set CGO
|
||||
set CGO_ENABLED=0
|
||||
|
||||
:: 检测系统语言 / Detect system language
|
||||
for /f "tokens=2 delims==" %%a in ('wmic os get OSLanguage /value') do set OSLanguage=%%a
|
||||
if "%OSLanguage%"=="2052" (set LANG=cn) else (set LANG=en)
|
||||
|
||||
:: 显示编译信息 / Display build info
|
||||
echo %YELLOW%!%LANG%_MESSAGES[0]! %VERSION%%RESET%
|
||||
echo %YELLOW%!%LANG%_MESSAGES[1]! LDFLAGS=%LDFLAGS%, BUILDMODE=%BUILDMODE%%RESET%
|
||||
echo %YELLOW%CGO_ENABLED=%CGO_ENABLED%%RESET%
|
||||
|
||||
:: 清理旧的构建文件 / Clean old builds
|
||||
echo %YELLOW%!%LANG%_MESSAGES[2]!%RESET%
|
||||
:: Cleanup function
|
||||
:cleanup
|
||||
if exist "..\bin" (
|
||||
rd /s /q "..\bin"
|
||||
echo %GREEN%!%LANG%_MESSAGES[3]!%RESET%
|
||||
) else (
|
||||
echo %YELLOW%!%LANG%_MESSAGES[4]!%RESET%
|
||||
echo %GREEN%!EN_MESSAGES[3]!%RESET%
|
||||
)
|
||||
|
||||
:: 创建输出目录 / Create output directory
|
||||
mkdir "..\bin" 2>nul
|
||||
|
||||
:: 定义目标平台数组 / Define target platforms array
|
||||
set platforms[0].os=windows
|
||||
set platforms[0].arch=amd64
|
||||
set platforms[0].ext=.exe
|
||||
set platforms[0].suffix=
|
||||
:: Build function with optimizations
|
||||
:build
|
||||
set "os=%~1"
|
||||
set "arch=%~2"
|
||||
set "ext="
|
||||
if "%os%"=="windows" set "ext=.exe"
|
||||
|
||||
set platforms[1].os=darwin
|
||||
set platforms[1].arch=amd64
|
||||
set platforms[1].ext=
|
||||
set platforms[1].suffix=_intel
|
||||
echo %GREEN%!EN_MESSAGES[5]! %os%/%arch%%RESET%
|
||||
|
||||
set platforms[2].os=darwin
|
||||
set platforms[2].arch=arm64
|
||||
set platforms[2].ext=
|
||||
set platforms[2].suffix=_m1
|
||||
set "CGO_ENABLED=0"
|
||||
set "GOOS=%os%"
|
||||
set "GOARCH=%arch%"
|
||||
|
||||
set platforms[3].os=linux
|
||||
set platforms[3].arch=amd64
|
||||
set platforms[3].ext=
|
||||
set platforms[3].suffix=
|
||||
start /b cmd /c "go build -trimpath -ldflags=\"-s -w\" -o ..\bin\%os%\%arch%\cursor-id-modifier%ext% -a -installsuffix cgo -mod=readonly ..\cmd\cursor-id-modifier"
|
||||
exit /b 0
|
||||
|
||||
:: 设置开始时间 / Set start time
|
||||
set start_time=%time%
|
||||
:: Main execution
|
||||
echo %GREEN%!EN_MESSAGES[0]!%RESET%
|
||||
echo %GREEN%!EN_MESSAGES[1]! %OPTIMIZATION_FLAGS%%RESET%
|
||||
|
||||
:: 编译所有目标 / Build all targets
|
||||
echo !%LANG%_MESSAGES[5]!
|
||||
call :cleanup
|
||||
|
||||
for /L %%i in (0,1,3) do (
|
||||
set "os=!platforms[%%i].os!"
|
||||
set "arch=!platforms[%%i].arch!"
|
||||
set "ext=!platforms[%%i].ext!"
|
||||
set "suffix=!platforms[%%i].suffix!"
|
||||
|
||||
echo.
|
||||
echo !%LANG%_MESSAGES[6]! !os! !arch!...
|
||||
|
||||
set GOOS=!os!
|
||||
set GOARCH=!arch!
|
||||
|
||||
:: 构建输出文件名 / Build output filename
|
||||
set "outfile=..\bin\cursor_id_modifier_v%VERSION%_!os!_!arch!!suffix!!ext!"
|
||||
|
||||
:: 执行构建 / Execute build
|
||||
go build -trimpath -buildmode=%BUILDMODE% -ldflags="%LDFLAGS%" -gcflags="%GCFLAGS%" -o "!outfile!" ..\main.go
|
||||
|
||||
if !errorlevel! equ 0 (
|
||||
echo %GREEN%!%LANG%_MESSAGES[7]! !outfile!%RESET%
|
||||
) else (
|
||||
echo %RED%!%LANG%_MESSAGES[8]! !os! !arch!%RESET%
|
||||
echo %GREEN%!EN_MESSAGES[4]!%RESET%
|
||||
|
||||
:: Start builds in parallel
|
||||
set "pending=0"
|
||||
for %%o in (windows linux darwin) do (
|
||||
for %%a in (amd64 386) do (
|
||||
call :build %%o %%a
|
||||
set /a "pending+=1"
|
||||
if !pending! geq %BUILD_JOBS% (
|
||||
timeout /t 1 /nobreak >nul
|
||||
set "pending=0"
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
:: 计算总耗时 / Calculate total time
|
||||
set end_time=%time%
|
||||
set /a duration = %end_time:~0,2% * 3600 + %end_time:~3,2% * 60 + %end_time:~6,2% - (%start_time:~0,2% * 3600 + %start_time:~3,2% * 60 + %start_time:~6,2%)
|
||||
:: Wait for all builds to complete
|
||||
:wait_builds
|
||||
timeout /t 2 /nobreak >nul
|
||||
tasklist /fi "IMAGENAME eq go.exe" 2>nul | find "go.exe" >nul
|
||||
if not errorlevel 1 goto wait_builds
|
||||
|
||||
echo.
|
||||
echo %GREEN%!%LANG%_MESSAGES[9]! %duration% !%LANG%_MESSAGES[10]!%RESET%
|
||||
if exist "..\bin" dir /b "..\bin"
|
||||
|
||||
pause
|
||||
endlocal
|
||||
echo %GREEN%!EN_MESSAGES[7]!%RESET%
|
||||
@@ -5,6 +5,10 @@ GREEN='\033[0;32m'
|
||||
RED='\033[0;31m'
|
||||
NC='\033[0m' # No Color / 无颜色
|
||||
|
||||
# Build optimization flags
|
||||
OPTIMIZATION_FLAGS="-trimpath -ldflags=\"-s -w\""
|
||||
PARALLEL_JOBS=$(nproc || echo "4") # Get number of CPU cores or default to 4
|
||||
|
||||
# Messages / 消息
|
||||
EN_MESSAGES=(
|
||||
"Starting build process for version"
|
||||
@@ -18,8 +22,6 @@ EN_MESSAGES=(
|
||||
"Successful builds:"
|
||||
"Failed builds:"
|
||||
"Generated files:"
|
||||
"Build process interrupted"
|
||||
"Error:"
|
||||
)
|
||||
|
||||
CN_MESSAGES=(
|
||||
@@ -70,82 +72,68 @@ handle_error() {
|
||||
|
||||
# 清理函数 / Cleanup function
|
||||
cleanup() {
|
||||
echo "$(get_message 1)"
|
||||
rm -rf ../bin
|
||||
if [ -d "../bin" ]; then
|
||||
rm -rf ../bin
|
||||
echo -e "${GREEN}$(get_message 1)${NC}"
|
||||
fi
|
||||
}
|
||||
|
||||
# 创建输出目录 / Create output directory
|
||||
create_output_dir() {
|
||||
echo "$(get_message 2)"
|
||||
mkdir -p ../bin || handle_error "$(get_message 3)"
|
||||
}
|
||||
|
||||
# 构建函数 / Build function
|
||||
# Build function with optimizations
|
||||
build() {
|
||||
local os=$1
|
||||
local arch=$2
|
||||
local suffix=$3
|
||||
local ext=""
|
||||
[ "$os" = "windows" ] && ext=".exe"
|
||||
|
||||
echo -e "\n$(get_message 4) $os ($arch)..."
|
||||
echo -e "${GREEN}$(get_message 4) $os/$arch${NC}"
|
||||
|
||||
output_name="../bin/cursor_id_modifier_v${VERSION}_${os}_${arch}${suffix}"
|
||||
|
||||
GOOS=$os GOARCH=$arch go build -o "$output_name" ../main.go
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo -e "${GREEN}✓ $(get_message 5) ${output_name}${NC}"
|
||||
else
|
||||
echo -e "${RED}✗ $(get_message 6) $os $arch${NC}"
|
||||
return 1
|
||||
fi
|
||||
GOOS=$os GOARCH=$arch CGO_ENABLED=0 go build \
|
||||
-trimpath \
|
||||
-ldflags="-s -w" \
|
||||
-o "../bin/$os/$arch/cursor-id-modifier$ext" \
|
||||
-a -installsuffix cgo \
|
||||
-mod=readonly \
|
||||
../cmd/cursor-id-modifier &
|
||||
}
|
||||
|
||||
# 主函数 / Main function
|
||||
main() {
|
||||
# 显示构建信息 / Display build info
|
||||
echo "$(get_message 0) ${VERSION}"
|
||||
# Parallel build execution
|
||||
build_all() {
|
||||
local builds=0
|
||||
local max_parallel=$PARALLEL_JOBS
|
||||
|
||||
# 清理旧文件 / Clean old files
|
||||
cleanup
|
||||
|
||||
# 创建输出目录 / Create output directory
|
||||
create_output_dir
|
||||
|
||||
# 定义构建目标 / Define build targets
|
||||
# Define build targets
|
||||
declare -A targets=(
|
||||
["windows_amd64"]=".exe"
|
||||
["darwin_amd64"]=""
|
||||
["darwin_arm64"]=""
|
||||
["linux_amd64"]=""
|
||||
["linux/amd64"]=1
|
||||
["linux/386"]=1
|
||||
["linux/arm64"]=1
|
||||
["windows/amd64"]=1
|
||||
["windows/386"]=1
|
||||
["darwin/amd64"]=1
|
||||
["darwin/arm64"]=1
|
||||
)
|
||||
|
||||
# 构建计数器 / Build counters
|
||||
local success_count=0
|
||||
local fail_count=0
|
||||
|
||||
# 遍历所有目标进行构建 / Build all targets
|
||||
for target in "${!targets[@]}"; do
|
||||
os=${target%_*}
|
||||
arch=${target#*_}
|
||||
suffix=${targets[$target]}
|
||||
IFS='/' read -r os arch <<< "$target"
|
||||
build "$os" "$arch"
|
||||
|
||||
if build "$os" "$arch" "$suffix"; then
|
||||
((success_count++))
|
||||
else
|
||||
((fail_count++))
|
||||
((builds++))
|
||||
|
||||
if ((builds >= max_parallel)); then
|
||||
wait
|
||||
builds=0
|
||||
fi
|
||||
done
|
||||
|
||||
# 显示构建结果 / Display build results
|
||||
echo -e "\n$(get_message 7)"
|
||||
echo -e "${GREEN}$(get_message 8) $success_count${NC}"
|
||||
if [ $fail_count -gt 0 ]; then
|
||||
echo -e "${RED}$(get_message 9) $fail_count${NC}"
|
||||
fi
|
||||
|
||||
# 显示生成的文件列表 / Display generated files
|
||||
echo -e "\n$(get_message 10)"
|
||||
ls -1 ../bin
|
||||
# Wait for remaining builds
|
||||
wait
|
||||
}
|
||||
|
||||
# Main execution
|
||||
main() {
|
||||
cleanup
|
||||
mkdir -p ../bin || { echo -e "${RED}$(get_message 3)${NC}"; exit 1; }
|
||||
build_all
|
||||
echo -e "${GREEN}Build completed successfully${NC}"
|
||||
}
|
||||
|
||||
# 捕获错误信号 / Catch error signals
|
||||
|
||||
@@ -6,303 +6,123 @@ if (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdenti
|
||||
Exit
|
||||
}
|
||||
|
||||
# Set TLS to 1.2 / 设置 TLS 为 1.2
|
||||
# Set TLS to 1.2
|
||||
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
|
||||
|
||||
# Colors for output / 输出颜色
|
||||
# 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' directly",
|
||||
"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:"
|
||||
)
|
||||
# Create temporary directory
|
||||
$TmpDir = Join-Path $env:TEMP ([System.Guid]::NewGuid().ToString())
|
||||
New-Item -ItemType Directory -Path $TmpDir | Out-Null
|
||||
|
||||
$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)
|
||||
}
|
||||
# Cleanup function
|
||||
function Cleanup {
|
||||
if (Test-Path $TmpDir) {
|
||||
Remove-Item -Recurse -Force $TmpDir
|
||||
}
|
||||
}
|
||||
|
||||
# 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"
|
||||
# Error handler
|
||||
trap {
|
||||
Write-Host "${Red}Error: $_${Reset}"
|
||||
Cleanup
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Detect system architecture
|
||||
function Get-SystemArch {
|
||||
if ([Environment]::Is64BitOperatingSystem) {
|
||||
return "amd64"
|
||||
} else {
|
||||
return "386"
|
||||
}
|
||||
}
|
||||
|
||||
# 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
|
||||
}
|
||||
|
||||
# 在文件开头添加日志函数
|
||||
function Write-Log {
|
||||
param(
|
||||
[string]$Message,
|
||||
[string]$Level = "INFO"
|
||||
)
|
||||
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
|
||||
$logMessage = "[$timestamp] [$Level] $Message"
|
||||
$logFile = "$env:TEMP\cursor-id-modifier-install.log"
|
||||
Add-Content -Path $logFile -Value $logMessage
|
||||
|
||||
# 同时输出到控制台
|
||||
switch ($Level) {
|
||||
"ERROR" { Write-Error $Message }
|
||||
"WARNING" { Write-Warning $Message }
|
||||
"SUCCESS" { Write-Success $Message }
|
||||
default { Write-Status $Message }
|
||||
}
|
||||
}
|
||||
|
||||
# 添加安装前检查函数
|
||||
function Test-Prerequisites {
|
||||
Write-Log "Checking prerequisites..." "INFO"
|
||||
|
||||
# 检查PowerShell版本
|
||||
if ($PSVersionTable.PSVersion.Major -lt 5) {
|
||||
Write-Log "PowerShell 5.0 or higher is required" "ERROR"
|
||||
return $false
|
||||
}
|
||||
|
||||
# 检查网络连接
|
||||
try {
|
||||
$testConnection = Test-Connection -ComputerName "github.com" -Count 1 -Quiet
|
||||
if (-not $testConnection) {
|
||||
Write-Log "No internet connection available" "ERROR"
|
||||
return $false
|
||||
}
|
||||
} catch {
|
||||
Write-Log "Failed to check internet connection: $_" "ERROR"
|
||||
return $false
|
||||
}
|
||||
|
||||
return $true
|
||||
}
|
||||
|
||||
# 添加文件验证函数
|
||||
function Test-FileHash {
|
||||
param(
|
||||
[string]$FilePath,
|
||||
[string]$ExpectedHash
|
||||
)
|
||||
|
||||
$actualHash = Get-FileHash -Path $FilePath -Algorithm SHA256
|
||||
return $actualHash.Hash -eq $ExpectedHash
|
||||
}
|
||||
|
||||
# 修改下载函数,添加进度条
|
||||
function Download-File {
|
||||
param(
|
||||
# Download with progress
|
||||
function Download-WithProgress {
|
||||
param (
|
||||
[string]$Url,
|
||||
[string]$OutFile
|
||||
[string]$OutputFile
|
||||
)
|
||||
|
||||
try {
|
||||
$webClient = New-Object System.Net.WebClient
|
||||
$webClient.Headers.Add("User-Agent", "PowerShell Script")
|
||||
|
||||
$webClient.DownloadFileAsync($Url, $OutFile)
|
||||
|
||||
while ($webClient.IsBusy) {
|
||||
Write-Progress -Activity "Downloading..." -Status "Progress:" -PercentComplete -1
|
||||
Start-Sleep -Milliseconds 100
|
||||
}
|
||||
|
||||
Write-Progress -Activity "Downloading..." -Completed
|
||||
$webClient.DownloadFile($Url, $OutputFile)
|
||||
return $true
|
||||
}
|
||||
catch {
|
||||
Write-Log "Download failed: $_" "ERROR"
|
||||
Write-Host "${Red}Failed to download: $_${Reset}"
|
||||
return $false
|
||||
}
|
||||
finally {
|
||||
if ($webClient) {
|
||||
$webClient.Dispose()
|
||||
}
|
||||
|
||||
# Main installation function
|
||||
function Install-CursorModifier {
|
||||
Write-Host "${Blue}Starting installation...${Reset}"
|
||||
|
||||
# Detect architecture
|
||||
$arch = Get-SystemArch
|
||||
Write-Host "${Green}Detected architecture: $arch${Reset}"
|
||||
|
||||
# Set installation directory
|
||||
$InstallDir = "$env:ProgramFiles\CursorModifier"
|
||||
if (!(Test-Path $InstallDir)) {
|
||||
New-Item -ItemType Directory -Path $InstallDir | Out-Null
|
||||
}
|
||||
|
||||
# Get latest release
|
||||
try {
|
||||
$latestRelease = Invoke-RestMethod -Uri "https://api.github.com/repos/dacrab/cursor-id-modifier/releases/latest"
|
||||
$downloadUrl = $latestRelease.assets | Where-Object { $_.name -match "windows_$arch" } | Select-Object -ExpandProperty browser_download_url
|
||||
|
||||
if (!$downloadUrl) {
|
||||
throw "Could not find download URL for windows_$arch"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# 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"
|
||||
$versionWithoutV = $version.TrimStart('v') # 移除版本号前面的 'v' 字符
|
||||
$binaryName = "cursor_id_modifier_${versionWithoutV}_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 {
|
||||
if (-not (Download-File -Url $downloadUrl -OutFile $tempFile)) {
|
||||
Write-Error "$(Get-Message 6)"
|
||||
catch {
|
||||
Write-Host "${Red}Failed to get latest release: $_${Reset}"
|
||||
exit 1
|
||||
}
|
||||
} catch {
|
||||
Write-Error "$(Get-Message 6) $_"
|
||||
|
||||
# Download binary
|
||||
Write-Host "${Blue}Downloading latest release...${Reset}"
|
||||
$binaryPath = Join-Path $TmpDir "cursor-id-modifier.exe"
|
||||
|
||||
if (!(Download-WithProgress -Url $downloadUrl -OutputFile $binaryPath)) {
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Install binary
|
||||
Write-Host "${Blue}Installing...${Reset}"
|
||||
try {
|
||||
Copy-Item -Path $binaryPath -Destination "$InstallDir\cursor-id-modifier.exe" -Force
|
||||
|
||||
# Add to PATH if not already present
|
||||
$currentPath = [Environment]::GetEnvironmentVariable("Path", "Machine")
|
||||
if ($currentPath -notlike "*$InstallDir*") {
|
||||
[Environment]::SetEnvironmentVariable("Path", "$currentPath;$InstallDir", "Machine")
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Write-Host "${Red}Failed to install: $_${Reset}"
|
||||
exit 1
|
||||
}
|
||||
|
||||
Write-Host "${Green}Installation completed successfully!${Reset}"
|
||||
Write-Host "${Blue}You can now run: cursor-id-modifier${Reset}"
|
||||
}
|
||||
|
||||
# Verify download / 验证下载
|
||||
if (-not (Test-Path $tempFile)) {
|
||||
Write-Error (Get-Message 7)
|
||||
}
|
||||
|
||||
# Install binary / 安装二进制文件
|
||||
Write-Status (Get-Message 8)
|
||||
# Run installation
|
||||
try {
|
||||
Move-Item -Force $tempFile "$installDir\cursor-id-modifier.exe"
|
||||
} catch {
|
||||
Write-Error "$(Get-Message 9) $_"
|
||||
Install-CursorModifier
|
||||
}
|
||||
|
||||
# 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"
|
||||
)
|
||||
}
|
||||
|
||||
# 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 ""
|
||||
|
||||
# 直接运行程序
|
||||
try {
|
||||
Start-Process "$installDir\cursor-id-modifier.exe" -NoNewWindow
|
||||
} catch {
|
||||
Write-Warning "Failed to start cursor-id-modifier: $_"
|
||||
finally {
|
||||
Cleanup
|
||||
}
|
||||
@@ -2,294 +2,98 @@
|
||||
|
||||
set -e
|
||||
|
||||
# Colors for output / 输出颜色
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
BLUE='\033[0;36m'
|
||||
YELLOW='\033[0;33m'
|
||||
NC='\033[0m' # No Color / 无颜色
|
||||
NC='\033[0m'
|
||||
|
||||
# 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..."
|
||||
)
|
||||
# Temporary directory for downloads
|
||||
TMP_DIR=$(mktemp -d)
|
||||
trap 'rm -rf "$TMP_DIR"' EXIT
|
||||
|
||||
CN_MESSAGES=(
|
||||
"开始安装..."
|
||||
"检测到操作系统:"
|
||||
"正在下载最新版本..."
|
||||
"下载地址:"
|
||||
"正在安装程序..."
|
||||
"正在清理..."
|
||||
"安装成功完成!"
|
||||
"现在可以在终端中使用 'sudo %s' 了"
|
||||
"从以下地址下载二进制文件失败:"
|
||||
"下载二进制文件失败"
|
||||
"需要 curl 但未安装。请先安装 curl。"
|
||||
"需要 sudo 但未安装。请先安装 sudo。"
|
||||
"不支持的操作系统"
|
||||
"不支持的架构:"
|
||||
"正在检查运行中的Cursor进程..."
|
||||
"发现正在运行的Cursor进程,尝试关闭..."
|
||||
"成功关闭所有Cursor实例"
|
||||
"无法关闭Cursor实例,请手动关闭"
|
||||
"正在备份storage.json..."
|
||||
"备份已创建于:"
|
||||
"此脚本需要root权限。正在请求sudo访问..."
|
||||
)
|
||||
# Detect system information
|
||||
detect_system() {
|
||||
local os arch
|
||||
|
||||
# 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 "darwin"
|
||||
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"
|
||||
;;
|
||||
case "$(uname -s)" in
|
||||
Linux*) os="linux";;
|
||||
Darwin*) os="darwin";;
|
||||
*) echo "Unsupported OS"; exit 1;;
|
||||
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)"
|
||||
;;
|
||||
x86_64) arch="amd64";;
|
||||
aarch64) arch="arm64";;
|
||||
arm64) arch="arm64";;
|
||||
*) echo "Unsupported architecture"; exit 1;;
|
||||
esac
|
||||
|
||||
echo "$os $arch"
|
||||
}
|
||||
|
||||
# Check for required tools / 检查必需工具
|
||||
check_requirements() {
|
||||
if ! command -v curl >/dev/null 2>&1; then
|
||||
print_error "$(get_message 10)"
|
||||
fi
|
||||
# Download with progress using curl or wget
|
||||
download() {
|
||||
local url="$1"
|
||||
local output="$2"
|
||||
|
||||
if ! command -v sudo >/dev/null 2>&1; then
|
||||
print_error "$(get_message 11)"
|
||||
if command -v curl >/dev/null 2>&1; then
|
||||
curl -#L "$url" -o "$output"
|
||||
elif command -v wget >/dev/null 2>&1; then
|
||||
wget --show-progress -q "$url" -O "$output"
|
||||
else
|
||||
echo "Error: curl or wget is required"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Main installation process / 主安装过程
|
||||
# Check and create installation directory
|
||||
setup_install_dir() {
|
||||
local install_dir="$1"
|
||||
|
||||
if [ ! -d "$install_dir" ]; then
|
||||
mkdir -p "$install_dir" || {
|
||||
echo "Failed to create installation directory"
|
||||
exit 1
|
||||
}
|
||||
fi
|
||||
}
|
||||
|
||||
# Main installation function
|
||||
main() {
|
||||
print_status "$(get_message 0)"
|
||||
echo -e "${BLUE}Starting installation...${NC}"
|
||||
|
||||
# Check root privileges / 检查root权限
|
||||
check_root "$@"
|
||||
# Detect system
|
||||
read -r OS ARCH <<< "$(detect_system)"
|
||||
echo -e "${GREEN}Detected: $OS $ARCH${NC}"
|
||||
|
||||
# Check required tools / 检查必需工具
|
||||
check_requirements
|
||||
# Set installation directory
|
||||
INSTALL_DIR="/usr/local/bin"
|
||||
[ "$OS" = "darwin" ] && INSTALL_DIR="/usr/local/bin"
|
||||
|
||||
# Close Cursor instances / 关闭Cursor实例
|
||||
close_cursor_instances
|
||||
# Setup installation directory
|
||||
setup_install_dir "$INSTALL_DIR"
|
||||
|
||||
# Backup storage.json / 备份storage.json
|
||||
backup_storage_json
|
||||
# Download latest release
|
||||
LATEST_URL="https://api.github.com/repos/dacrab/cursor-id-modifier/releases/latest"
|
||||
DOWNLOAD_URL=$(curl -s "$LATEST_URL" | grep "browser_download_url.*${OS}_${ARCH}" | cut -d '"' -f 4)
|
||||
|
||||
OS=$(detect_os)
|
||||
print_status "$(get_message 1) $OS"
|
||||
if [ -z "$DOWNLOAD_URL" ]; then
|
||||
echo -e "${RED}Error: Could not find download URL for $OS $ARCH${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Install the binary / 安装二进制文件
|
||||
install_binary
|
||||
echo -e "${BLUE}Downloading latest release...${NC}"
|
||||
download "$DOWNLOAD_URL" "$TMP_DIR/cursor-id-modifier"
|
||||
|
||||
# Install binary
|
||||
echo -e "${BLUE}Installing...${NC}"
|
||||
chmod +x "$TMP_DIR/cursor-id-modifier"
|
||||
sudo mv "$TMP_DIR/cursor-id-modifier" "$INSTALL_DIR/"
|
||||
|
||||
echo -e "${GREEN}Installation completed successfully!${NC}"
|
||||
echo -e "${BLUE}You can now run: cursor-id-modifier${NC}"
|
||||
}
|
||||
|
||||
# Run main function / 运行主函数
|
||||
main "$@"
|
||||
main
|
||||
|
||||
Reference in New Issue
Block a user