gitlink-cli/install.ps1

442 lines
12 KiB
PowerShell
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.

# GitLink CLI Windows 安装脚本
# 用法: powershell -NoProfile -ExecutionPolicy Bypass -File install.ps1
# 支持: .\install.ps1 -Version 0.1.0 -InstallDir "C:\GitLink"
param(
[string]$Version = "latest",
[string]$InstallDir = "$HOME\.gitlink-cli\bin",
[switch]$Help = $false,
[switch]$Uninstall = $false,
[switch]$ListVersions = $false,
[switch]$Debug = $false
)
$ErrorActionPreference = "Stop"
$REPO_OWNER = "Gitlink"
$REPO_NAME = "gitlink-cli"
$BINARY_NAME = "gitlink-cli"
$API_BASE = "https://www.gitlink.org.cn"
$SKILLS_DIR = "$HOME\.gitlink\skills"
# 颜色输出
function Info {
param([string]$msg)
Write-Host "[INFO] $msg" -ForegroundColor Green
}
function Warn {
param([string]$msg)
Write-Host "[WARN] $msg" -ForegroundColor Yellow
}
function ErrorMsg {
param([string]$msg)
Write-Host "[ERROR] $msg" -ForegroundColor Red
}
function Step {
param([string]$msg)
Write-Host "[STEP] $msg" -ForegroundColor Cyan
}
function DebugMsg {
param([string]$msg)
if ($Debug) {
Write-Host "[DEBUG] $msg" -ForegroundColor Blue
}
}
# 显示帮助
function Show-Help {
Write-Host @"
GitLink CLI Windows
:
.\install.ps1 []
:
-Version <version> (: latest)
-InstallDir <path> (: $HOME\.gitlink-cli\bin)
-Uninstall
-ListVersions
-Debug
-Help
:
#
.\install.ps1
#
.\install.ps1 -Version "0.1.0"
#
.\install.ps1 -InstallDir "C:\Tools\gitlink-cli"
#
.\install.ps1 -ListVersions
#
.\install.ps1 -Uninstall
# 线
powershell -NoProfile -ExecutionPolicy Bypass -Command "iex (irm https://www.gitlink.org.cn/Gitlink/gitlink-cli/raw/master/install.ps1)"
"@
}
# 检测架构
function Get-PlatformInfo {
$arch = switch ([System.Runtime.InteropServices::RuntimeInformation]::OSArchitecture) {
"X64" { "amd64" }
"Arm64" { "arm64" }
"X86" { "386"; Warn "32位系统支持有限" }
default { throw "不支持的架构: $arch" }
}
return @{ Platform = "windows"; Arch = $arch }
}
# 检查环境
function Test-Environment {
Step "检查安装环境..."
# 检查磁盘空间至少50MB
$drive = (Get-Item $InstallDir).PSDrive.Name
$driveInfo = Get-PSDrive $drive
$freeSpaceMB = [math]::Round($driveInfo.Free / 1MB, 2)
if ($freeSpaceMB -lt 50) {
ErrorMsg "磁盘空间不足需要至少50MB可用: ${freeSpaceMB}MB"
exit 1
}
DebugMsg "磁盘空间检查通过: ${freeSpaceMB}MB"
# 检查网络连接
try {
$response = Invoke-WebRequest -Uri $API_BASE -UseBasicParsing -TimeoutSec 5 -Method Head
DebugMsg "网络连接检查通过"
}
catch {
ErrorMsg "无法连接到 GitLink 服务器: $API_BASE"
ErrorMsg "请检查网络连接"
exit 1
}
Info "环境检查通过"
}
# 下载文件(带重试)
function Download-File {
param(
[string]$Url,
[string]$Output,
[int]$MaxAttempts = 3
)
$attempt = 1
while ($attempt -le $MaxAttempts) {
try {
Step "下载 (尝试 $attempt/$MaxAttempts): $(Split-Path $Url -Leaf)"
DebugMsg "URL: $Url"
# 使用WebClient支持进度显示
$webClient = New-Object System.Net.WebClient
# 注册下载进度事件
Register-ObjectEvent -InputObject $webClient -EventName DownloadProgressChanged -SourceIdentifier WebClient.DownloadProgressChanged -Action {
global:Progress = $EventArgs.ProgressPercentage
Write-Progress -Activity "下载中" -Status "$($EventArgs.ProgressPercentage)% 完成" -PercentComplete $EventArgs.ProgressPercentage
} | Out-Null
# 注册下载完成事件
Register-ObjectEvent -InputObject $webClient -EventName DownloadFileCompleted -SourceIdentifier WebClient.DownloadFileCompleted -Action {
global:DownloadComplete = $true
} | Out-Null
# 开始下载
$webClient.DownloadFileAsync($Url, $Output)
# 等待下载完成
while (-not $global:DownloadComplete) {
Start-Sleep -Milliseconds 100
}
Write-Progress -Activity "下载中" -Completed
# 清理事件
Unregister-Event -SourceIdentifier WebClient.DownloadProgressChanged -ErrorAction SilentlyContinue
Unregister-Event -SourceIdentifier WebClient.DownloadFileCompleted -ErrorAction SilentlyContinue
$webClient.Dispose()
if (Test-Path $Output) {
$size = [math]::Round((Get-Item $Output).Length / 1MB, 2)
Info "下载成功: $(Split-Path $Output -Leaf) (${size}MB)"
return $true
}
else {
Warn "下载文件为空"
}
}
catch {
Warn "下载失败: $_"
}
if ($attempt -lt $MaxAttempts) {
$waitTime = $attempt * 2
Warn "等待 ${waitTime}s 后重试..."
Start-Sleep -Seconds $waitTime
}
$attempt++
}
ErrorMsg "下载失败,已尝试 $MaxAttempts"
ErrorMsg "URL: $Url"
return $false
}
# 获取最新版本
function Get-LatestVersion {
Step "获取最新版本..."
try {
$releasesUrl = "$API_BASE/api/$REPO_OWNER/$REPO_NAME/releases.json"
$releases = Invoke-RestMethod -Uri $releasesUrl -TimeoutSec 30 -UseBasicParsing
if ($releases -and $releases.Count -gt 0) {
return $releases[0].tag_name
}
else {
Warn "无法获取版本信息,使用默认版本"
return "v0.1.0"
}
}
catch {
Warn "获取版本失败: $_"
return "v0.1.0"
}
}
# 列出可用版本
function Show-AvailableVersions {
Step "查询可用版本..."
try {
$releasesUrl = "$API_BASE/api/$REPO_OWNER/$REPO_NAME/releases.json"
$releases = Invoke-RestMethod -Uri $releasesUrl -TimeoutSec 30 -UseBasicParsing
if ($releases -and $releases.Count -gt 0) {
Info "可用版本:"
foreach ($release in $releases | Select-Object -First 10) {
Write-Host " - $($release.tag_name)" -ForegroundColor Cyan
}
}
else {
Warn "无法获取版本列表"
}
}
catch {
ErrorMsg "获取版本列表失败: $_"
}
}
# 解压zip文件
function Expand-ZipFile {
param(
[string]$ZipPath,
[string]$DestDir
)
Step "解压..."
DebugMsg "解压 $ZipPath$DestDir"
try {
Expand-Archive -Force -Path $ZipPath -DestinationPath $DestDir
Info "解压完成"
}
catch {
ErrorMsg "解压失败: $_"
throw
}
}
# 添加到PATH
function Add-ToPath {
param([string]$Dir)
$path = [Environment]::GetEnvironmentVariable("Path", "User")
if ($path -notlike "*$Dir*") {
Step "添加到PATH: $Dir"
[Environment]::SetEnvironmentVariable("Path", "$path;$Dir", "User")
Warn "请重启终端使PATH生效"
}
else {
DebugMsg "已在PATH中: $Dir"
}
}
# 验证安装
function Test-Installation {
Step "验证安装..."
$binaryPath = Join-Path $InstallDir "$BINARY_NAME.exe"
if (Test-Path $binaryPath) {
try {
$versionOutput = & $binaryPath version 2>$null
Info "安装成功! $versionOutput"
# 添加到PATH
Add-ToPath $InstallDir
Write-Host ""
Info "快速开始:"
Info " gitlink-cli auth login # 登录账号"
Info " gitlink-cli --help # 查看所有命令"
Info " gitlink-cli version # 查看版本信息"
Write-Host ""
return $true
}
catch {
ErrorMsg "执行二进制文件失败: $_"
return $false
}
}
else {
ErrorMsg "安装验证失败: $binaryPath 不存在"
return $false
}
}
# 主安装流程
function Install-CLI {
Write-Host ""
Write-Host " ╔══════════════════════════════════════╗"
Write-Host " ║ GitLink CLI 一键安装 (Windows) ║"
Write-Host " ╚══════════════════════════════════════╝"
Write-Host ""
# 检测平台
$platform = Get-PlatformInfo
Info "检测到平台: $($platform.Platform)-$($platform.Arch)"
# 创建安装目录
if (!(Test-Path $InstallDir)) {
New-Item -ItemType Directory -Path $InstallDir -Force | Out-Null
Info "创建安装目录: $InstallDir"
}
# 检查环境
Test-Environment
# 获取版本
if ($Version -eq "latest") {
$Version = Get-LatestVersion
Info "最新版本: $Version"
}
else {
Info "指定版本: $Version"
}
# 下载
$zipName = "$BINARY_NAME_${Version}_windows_$($platform.Arch).zip"
$zipUrl = "$API_BASE/api/$REPO_OWNER/$REPO_NAME/releases/$Version/assets/$zipName"
$zipPath = Join-Path $env:TEMP $zipName
if (-not (Download-File -Url $zipUrl -Output $zipPath)) {
ErrorMsg "请确认以下版本已发布: $Version"
ErrorMsg "发布页: $API_BASE/$REPO_OWNER/$REPO_NAME/releases"
exit 1
}
# 解压
Expand-ZipFile -ZipPath $zipPath -DestDir $InstallDir
Remove-Item $zipPath
# 安装skills
Step "安装 skills..."
if (!(Test-Path $SKILLS_DIR)) {
New-Item -ItemType Directory -Path $SKILLS_DIR -Force | Out-Null
}
$skillsZipName = "$BINARY_NAME_${Version}_skills.zip"
$skillsUrl = "$API_BASE/api/$REPO_OWNER/$REPO_NAME/releases/$Version/assets/$skillsZipName"
$skillsZipPath = Join-Path $env:TEMP $skillsZipName
if (Download-File -Url $skillsUrl -Output $skillsZipPath) {
try {
Expand-Archive -Force -Path $skillsZipPath -DestinationPath $SKILLS_DIR
Info "Skills 安装到: $SKILLS_DIR"
}
catch {
Warn "Skills 解压失败(可稍后手动安装)"
}
Remove-Item $skillsZipPath -ErrorAction SilentlyContinue
}
else {
Warn "Skills 包不可用(可稍后手动安装)"
}
# 验证
if (-not (Test-Installation)) {
exit 1
}
}
# 卸载
function Uninstall-CLI {
Step "卸载 $BINARY_NAME..."
# 删除二进制
$binaryPath = Join-Path $InstallDir "$BINARY_NAME.exe"
if (Test-Path $binaryPath) {
Remove-Item $binaryPath -Force
Info "已删除: $binaryPath"
}
# 删除skills
if (Test-Path $SKILLS_DIR) {
Remove-Item $SKILLS_DIR -Recurse -Force
Info "已删除: $SKILLS_DIR"
}
# 删除配置(可选)
$response = Read-Host "是否删除配置文件? [y/N]"
if ($response -eq 'y' -or $response -eq 'Y') {
$configDir = Join-Path $env:APPDATA "gitlink-cli"
if (Test-Path $configDir) {
Remove-Item $configDir -Recurse -Force
Info "已删除配置文件"
}
}
Info "卸载完成"
}
# 主函数
function Main {
if ($Help) {
Show-Help
exit 0
}
if ($ListVersions) {
Show-AvailableVersions
exit 0
}
if ($Uninstall) {
Uninstall-CLI
exit 0
}
try {
Install-CLI
}
catch {
ErrorMsg "安装失败: $_"
exit 1
}
}
Main