feat: ask install directory, support non-root on Linux
- Remove forced root check; detect user and default to ~/.local/hapi for non-root, /opt/hapi for root - Interactive prompt to confirm or customize install directory - Non-root users can install CLI but get warned about Docker/systemd limitations - Windows: ask to confirm C:\hapi or enter custom path - Hub/autostart options grayed out when prerequisites unavailable via [HAPI](https://hapi.run) Co-Authored-By: HAPI <[email protected]>
This commit is contained in:
+116
-61
@@ -9,6 +9,9 @@
|
||||
2. 提供交互式菜单:安装、升级、重装、卸载、Hub 管理、开机自启
|
||||
3. 支持命令行快速模式(向后兼容)
|
||||
|
||||
.PARAMETER InstallDir
|
||||
指定安装目录(默认: C:\hapi)
|
||||
|
||||
.PARAMETER Source
|
||||
指定 HAPI CLI 安装来源:npm, github-official, github-fork
|
||||
|
||||
@@ -23,6 +26,7 @@
|
||||
|
||||
.EXAMPLE
|
||||
.\install.ps1
|
||||
.\install.ps1 -InstallDir D:\hapi
|
||||
.\install.ps1 -Source npm
|
||||
.\install.ps1 -Source github-official
|
||||
.\install.ps1 -Force
|
||||
@@ -34,6 +38,8 @@
|
||||
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[string]$InstallDir = "",
|
||||
|
||||
[ValidateSet("npm", "github-official", "github-fork", "")]
|
||||
[string]$Source = "",
|
||||
|
||||
@@ -48,14 +54,14 @@ param(
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
# ─────────────────────────────────────────
|
||||
# 配置常量
|
||||
# 默认配置(会在 Setup-InstallDir 中被覆盖)
|
||||
# ─────────────────────────────────────────
|
||||
$INSTALL_DIR = "C:\hapi"
|
||||
$HAPI_BIN_DIR = "$INSTALL_DIR\bin"
|
||||
$HAPI_DATA = "$INSTALL_DIR\hapi-data"
|
||||
$INSTALL_DIR = ""
|
||||
$HAPI_BIN_DIR = ""
|
||||
$HAPI_DATA = ""
|
||||
$LOG_FILE = "$env:TEMP\hapi-install.log"
|
||||
$VERSION_FILE = "$INSTALL_DIR\.hapi-version"
|
||||
$SOURCE_FILE = "$INSTALL_DIR\.hapi-source"
|
||||
$VERSION_FILE = ""
|
||||
$SOURCE_FILE = ""
|
||||
$NODE_MIN_MAJOR = 22
|
||||
|
||||
$NPM_PACKAGE = "@twsxtd/hapi"
|
||||
@@ -76,6 +82,7 @@ $STATUS_HUB_RUNNING = $false
|
||||
$STATUS_HUB_CONFIGURED = $false
|
||||
$STATUS_AUTOSTART_HUB = $null
|
||||
$STATUS_AUTOSTART_RUNNER = $null
|
||||
$HAS_DOCKER = $false
|
||||
|
||||
# ─────────────────────────────────────────
|
||||
# 输出函数
|
||||
@@ -86,6 +93,35 @@ function Write-Ok { param($msg) Write-Host "[OK] $msg" -ForegroundColor Gree
|
||||
function Write-Warn { param($msg) Write-Host "[WARN] $msg" -ForegroundColor Yellow; "[WARN] $msg" | Out-File $LOG_FILE -Append }
|
||||
function Write-Err { param($msg) Write-Host "[ERR] $msg" -ForegroundColor Red; "[ERR] $msg" | Out-File $LOG_FILE -Append }
|
||||
|
||||
# ─────────────────────────────────────────
|
||||
# 设置安装目录
|
||||
# ─────────────────────────────────────────
|
||||
function Setup-InstallDir {
|
||||
$defaultDir = "C:\hapi"
|
||||
|
||||
if ($InstallDir) {
|
||||
$script:INSTALL_DIR = $InstallDir
|
||||
} else {
|
||||
Write-Host ""
|
||||
Write-Info "请选择 HAPI 安装目录"
|
||||
Write-Host " 默认: $defaultDir"
|
||||
Write-Host ""
|
||||
$userDir = Read-Host "按 Enter 使用默认,或输入自定义路径"
|
||||
if ($userDir) {
|
||||
$script:INSTALL_DIR = $userDir
|
||||
} else {
|
||||
$script:INSTALL_DIR = $defaultDir
|
||||
}
|
||||
}
|
||||
|
||||
$script:HAPI_BIN_DIR = Join-Path $script:INSTALL_DIR "bin"
|
||||
$script:HAPI_DATA = Join-Path $script:INSTALL_DIR "hapi-data"
|
||||
$script:VERSION_FILE = Join-Path $script:INSTALL_DIR ".hapi-version"
|
||||
$script:SOURCE_FILE = Join-Path $script:INSTALL_DIR ".hapi-source"
|
||||
|
||||
Write-Ok "安装目录: $($script:INSTALL_DIR)"
|
||||
}
|
||||
|
||||
# ─────────────────────────────────────────
|
||||
# GitHub 镜像 URL 替换
|
||||
# ─────────────────────────────────────────
|
||||
@@ -453,28 +489,33 @@ function Install-NodeJS {
|
||||
# ─────────────────────────────────────────
|
||||
# 检查 Docker
|
||||
# ─────────────────────────────────────────
|
||||
function Install-Docker {
|
||||
Write-Step "检查 Docker"
|
||||
function Check-Docker {
|
||||
$docker = Get-Command "docker" -ErrorAction SilentlyContinue
|
||||
if ($docker) {
|
||||
Write-Ok "Docker 已安装"
|
||||
return
|
||||
try {
|
||||
$null = & docker info 2>$null
|
||||
$script:HAS_DOCKER = $true
|
||||
return
|
||||
} catch {}
|
||||
}
|
||||
Write-Warn "未检测到 Docker"
|
||||
Write-Warn "请手动安装 Docker Desktop: https://docs.docker.com/desktop/install/windows-install/"
|
||||
Write-Warn "安装完成后请重新运行此脚本"
|
||||
throw "Docker 未安装"
|
||||
$script:HAS_DOCKER = $false
|
||||
}
|
||||
|
||||
# ─────────────────────────────────────────
|
||||
# 配置 HAPI Hub
|
||||
# ─────────────────────────────────────────
|
||||
function Setup-Hub {
|
||||
Write-Step "配置 HAPI Hub"
|
||||
New-Item -ItemType Directory -Force -Path $INSTALL_DIR | Out-Null
|
||||
New-Item -ItemType Directory -Force -Path $HAPI_DATA | Out-Null
|
||||
if (-not $script:HAS_DOCKER) {
|
||||
Write-Err "Docker 不可用,无法配置 Hub"
|
||||
Write-Warn "请安装 Docker Desktop: https://docs.docker.com/desktop/install/windows-install/"
|
||||
return
|
||||
}
|
||||
|
||||
$envPath = Join-Path $INSTALL_DIR ".env"
|
||||
Write-Step "配置 HAPI Hub"
|
||||
New-Item -ItemType Directory -Force -Path $script:INSTALL_DIR | Out-Null
|
||||
New-Item -ItemType Directory -Force -Path $script:HAPI_DATA | Out-Null
|
||||
|
||||
$envPath = Join-Path $script:INSTALL_DIR ".env"
|
||||
if (Test-Path $envPath) {
|
||||
$content = Get-Content $envPath -Raw
|
||||
$tokenMatch = [regex]::Match($content, 'CLI_API_TOKEN=(.+?)\r?\n')
|
||||
@@ -506,7 +547,7 @@ TZ=Asia/Shanghai
|
||||
Write-Ok "已生成配置文件"
|
||||
}
|
||||
|
||||
$composePath = Join-Path $INSTALL_DIR "docker-compose.yml"
|
||||
$composePath = Join-Path $script:INSTALL_DIR "docker-compose.yml"
|
||||
$composeContent = @"
|
||||
services:
|
||||
hapi-hub:
|
||||
@@ -525,7 +566,7 @@ services:
|
||||
"@
|
||||
$composeContent | Set-Content $composePath -Encoding UTF8
|
||||
|
||||
Push-Location $INSTALL_DIR
|
||||
Push-Location $script:INSTALL_DIR
|
||||
docker compose pull | Out-File $LOG_FILE -Append
|
||||
docker compose up -d | Out-File $LOG_FILE -Append
|
||||
Pop-Location
|
||||
@@ -545,13 +586,17 @@ services:
|
||||
# 停止 HAPI Hub
|
||||
# ─────────────────────────────────────────
|
||||
function Stop-Hub {
|
||||
$composePath = Join-Path $INSTALL_DIR "docker-compose.yml"
|
||||
$composePath = Join-Path $script:INSTALL_DIR "docker-compose.yml"
|
||||
if (-not (Test-Path $composePath)) {
|
||||
Write-Warn "未找到 Hub 配置,无需停止"
|
||||
return
|
||||
}
|
||||
if (-not $script:HAS_DOCKER) {
|
||||
Write-Err "Docker 不可用"
|
||||
return
|
||||
}
|
||||
Write-Step "停止 HAPI Hub"
|
||||
Push-Location $INSTALL_DIR
|
||||
Push-Location $script:INSTALL_DIR
|
||||
docker compose down | Out-File $LOG_FILE -Append
|
||||
Pop-Location
|
||||
Write-Ok "HAPI Hub 已停止"
|
||||
@@ -561,12 +606,16 @@ function Stop-Hub {
|
||||
# 启动 HAPI Hub
|
||||
# ─────────────────────────────────────────
|
||||
function Start-HubOnly {
|
||||
$composePath = Join-Path $INSTALL_DIR "docker-compose.yml"
|
||||
if (-not $script:HAS_DOCKER) {
|
||||
Write-Err "Docker 不可用"
|
||||
return
|
||||
}
|
||||
$composePath = Join-Path $script:INSTALL_DIR "docker-compose.yml"
|
||||
if (-not (Test-Path $composePath)) {
|
||||
Write-Warn "未找到 Hub 配置"
|
||||
return
|
||||
}
|
||||
Push-Location $INSTALL_DIR
|
||||
Push-Location $script:INSTALL_DIR
|
||||
docker compose up -d | Out-File $LOG_FILE -Append
|
||||
Pop-Location
|
||||
Write-Ok "HAPI Hub 已启动"
|
||||
@@ -578,9 +627,9 @@ function Start-HubOnly {
|
||||
function Setup-AutoStart {
|
||||
Write-Step "创建开机自启计划任务"
|
||||
|
||||
$hubScriptPath = Join-Path $INSTALL_DIR "start-hub.ps1"
|
||||
$hubScriptPath = Join-Path $script:INSTALL_DIR "start-hub.ps1"
|
||||
$hubScript = @"
|
||||
Set-Location "$INSTALL_DIR"
|
||||
Set-Location "$($script:INSTALL_DIR)"
|
||||
docker compose up -d
|
||||
"@
|
||||
$hubScript | Set-Content $hubScriptPath -Encoding UTF8
|
||||
@@ -607,13 +656,13 @@ docker compose up -d
|
||||
$settingsJson = @"
|
||||
{
|
||||
`"apiUrl`": `"http://localhost:3006`",
|
||||
`"cliApiToken`": `"$script:CLI_TOKEN`"
|
||||
`"cliApiToken`": `"$($script:CLI_TOKEN)`"
|
||||
}
|
||||
"@
|
||||
$settingsJson | Set-Content (Join-Path $hapiHome "settings.json") -Encoding UTF8
|
||||
|
||||
$hapiExe = (Get-Command hapi -ErrorAction SilentlyContinue).Source
|
||||
if (-not $hapiExe) { $hapiExe = Join-Path $HAPI_BIN_DIR "hapi.exe" }
|
||||
if (-not $hapiExe) { $hapiExe = Join-Path $script:HAPI_BIN_DIR "hapi.exe" }
|
||||
|
||||
$trigger2 = New-ScheduledTaskTrigger -AtLogon
|
||||
$action2 = New-ScheduledTaskAction -Execute "powershell.exe" `
|
||||
@@ -736,11 +785,13 @@ function Collect-Status {
|
||||
if (-not $script:STATUS_CLI_PATH) { $script:STATUS_CLI_PATH = "" }
|
||||
}
|
||||
|
||||
$composePath = Join-Path $INSTALL_DIR "docker-compose.yml"
|
||||
$composePath = Join-Path $script:INSTALL_DIR "docker-compose.yml"
|
||||
if (Test-Path $composePath) {
|
||||
$script:STATUS_HUB_CONFIGURED = $true
|
||||
$containers = (& docker ps --format '{{.Names}}' 2>$null) | Where-Object { $_ -eq "hapi-hub" }
|
||||
if ($containers) { $script:STATUS_HUB_RUNNING = $true }
|
||||
if ($script:HAS_DOCKER) {
|
||||
$containers = (& docker ps --format '{{.Names}}' 2>$null) | Where-Object { $_ -eq "hapi-hub" }
|
||||
if ($containers) { $script:STATUS_HUB_RUNNING = $true }
|
||||
}
|
||||
}
|
||||
|
||||
$hubTask = Get-ScheduledTask -TaskName "HAPI Hub" -ErrorAction SilentlyContinue
|
||||
@@ -814,7 +865,7 @@ function Print-Status {
|
||||
$hubLine = $hubLine.PadRight(67) + "║"
|
||||
Write-Host $hubLine -ForegroundColor White
|
||||
if ($script:STATUS_HUB_CONFIGURED) {
|
||||
$cfgLine = "║ 配置: $INSTALL_DIR"
|
||||
$cfgLine = "║ 配置: $($script:INSTALL_DIR)"
|
||||
$cfgLine = $cfgLine.PadRight(67) + "║"
|
||||
Write-Host $cfgLine -ForegroundColor White
|
||||
}
|
||||
@@ -863,19 +914,23 @@ function Main-Menu {
|
||||
|
||||
Write-Host ""
|
||||
|
||||
if (-not $script:STATUS_HUB_CONFIGURED) {
|
||||
Write-Host " $i) 配置并启动 HAPI Hub"
|
||||
$options += "hub"
|
||||
$i++
|
||||
} else {
|
||||
if ($script:STATUS_HUB_RUNNING) {
|
||||
Write-Host " $i) 停止 HAPI Hub"
|
||||
$options += "stop_hub"
|
||||
if ($script:HAS_DOCKER) {
|
||||
if (-not $script:STATUS_HUB_CONFIGURED) {
|
||||
Write-Host " $i) 配置并启动 HAPI Hub"
|
||||
$options += "hub"
|
||||
$i++
|
||||
} else {
|
||||
Write-Host " $i) 启动 HAPI Hub"
|
||||
$options += "start_hub"
|
||||
if ($script:STATUS_HUB_RUNNING) {
|
||||
Write-Host " $i) 停止 HAPI Hub"
|
||||
$options += "stop_hub"
|
||||
} else {
|
||||
Write-Host " $i) 启动 HAPI Hub"
|
||||
$options += "start_hub"
|
||||
}
|
||||
$i++
|
||||
}
|
||||
$i++
|
||||
} else {
|
||||
Write-Host " Hub 管理 (Docker 不可用)" -ForegroundColor DarkGray
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
@@ -1033,12 +1088,7 @@ function Execute-Uninstall {
|
||||
# 菜单操作:Hub 相关
|
||||
# ─────────────────────────────────────────
|
||||
function Execute-HubSetup {
|
||||
try {
|
||||
Install-Docker
|
||||
Setup-Hub
|
||||
} catch {
|
||||
Write-Err "Hub 配置失败: $_"
|
||||
}
|
||||
Setup-Hub
|
||||
Collect-Status
|
||||
Read-Host "按 Enter 继续..."
|
||||
}
|
||||
@@ -1061,14 +1111,7 @@ function Execute-StopHub {
|
||||
function Execute-SetupAutoStart {
|
||||
if (-not $script:STATUS_HUB_CONFIGURED) {
|
||||
Write-Warn "Hub 未配置,先执行配置并启动 HAPI Hub"
|
||||
try {
|
||||
Install-Docker
|
||||
Setup-Hub
|
||||
} catch {
|
||||
Write-Err "Hub 配置失败: $_"
|
||||
Read-Host "按 Enter 继续..."
|
||||
return
|
||||
}
|
||||
Setup-Hub
|
||||
}
|
||||
Setup-AutoStart
|
||||
Collect-Status
|
||||
@@ -1095,6 +1138,15 @@ function Check-Prerequisites {
|
||||
}
|
||||
}
|
||||
Write-Ok "基础工具检查通过"
|
||||
|
||||
Check-Docker
|
||||
if ($script:HAS_DOCKER) {
|
||||
Write-Ok "Docker 可用"
|
||||
} else {
|
||||
Write-Warn "Docker 不可用"
|
||||
Write-Warn "Hub 管理功能将不可用"
|
||||
Write-Warn "请安装 Docker Desktop: https://docs.docker.com/desktop/install/windows-install/"
|
||||
}
|
||||
}
|
||||
|
||||
# ─────────────────────────────────────────
|
||||
@@ -1142,9 +1194,10 @@ function Run-QuickMode {
|
||||
"github-fork" { Install-FromGithub -repo $GITHUB_FORK_REPO | Out-Null }
|
||||
}
|
||||
|
||||
Install-Docker
|
||||
if (-not $SkipHub) { Setup-Hub }
|
||||
if (-not $SkipHub) { Setup-AutoStart }
|
||||
if ($script:HAS_DOCKER -and -not $SkipHub) {
|
||||
Setup-Hub
|
||||
Setup-AutoStart
|
||||
}
|
||||
}
|
||||
|
||||
# ─────────────────────────────────────────
|
||||
@@ -1153,12 +1206,13 @@ function Run-QuickMode {
|
||||
"" | Out-File $LOG_FILE
|
||||
|
||||
# 如果带有旧版参数,进入快速模式
|
||||
if ($Upgrade -or $Force -or $Source -or $SkipHub) {
|
||||
if ($Upgrade -or $Force -or $Source -or $SkipHub -or $InstallDir) {
|
||||
Write-Host ""
|
||||
Write-Host "╔══════════════════════════════════════════════════════════════════╗" -ForegroundColor White
|
||||
Write-Host "║ HAPI 快速模式 ║" -ForegroundColor White
|
||||
Write-Host "╚══════════════════════════════════════════════════════════════════╝" -ForegroundColor White
|
||||
Write-Host ""
|
||||
Setup-InstallDir
|
||||
Check-Prerequisites
|
||||
Run-QuickMode
|
||||
exit 0
|
||||
@@ -1171,6 +1225,7 @@ Write-Host "║ 状态查看 | 安装升级 | 开机自启 | Hub 管
|
||||
Write-Host "╚══════════════════════════════════════════════════════════════════╝" -ForegroundColor White
|
||||
Write-Host ""
|
||||
|
||||
Setup-InstallDir
|
||||
Check-Prerequisites
|
||||
Collect-Status
|
||||
|
||||
|
||||
Reference in New Issue
Block a user