unarr/install.ps1
Deivid Soto 5a7449b9e6 chore: rename module from torrentclaw-cli to unarr
- Rename Go module path github.com/torrentclaw/torrentclaw-cli → github.com/torrentclaw/unarr
- Update all imports, ldflags, scripts, docs, and Docker config
- Add GitHub Actions release workflow (goreleaser on tag push)
2026-03-30 13:06:07 +02:00

254 lines
8.2 KiB
PowerShell

# unarr — Windows installer (PowerShell 5.1+)
# Usage: irm https://get.unarr.com/install.ps1 | iex
# or: irm https://raw.githubusercontent.com/torrentclaw/unarr/main/install.ps1 | iex
#
# Options (env vars):
# $env:INSTALL_DIR = "C:\path" — where to place the binary
# $env:VERSION = "0.5.0" — specific version
# $env:METHOD = "binary|docker" — force install method
param(
[string]$Method,
[string]$Version,
[string]$InstallDir
)
$ErrorActionPreference = "Stop"
$Repo = "torrentclaw/unarr"
$Binary = "unarr.exe"
# ---- Helpers ----
function Write-Info { param($msg) Write-Host "$msg" -ForegroundColor Cyan }
function Write-Ok { param($msg) Write-Host "$msg" -ForegroundColor Green }
function Write-Warn { param($msg) Write-Host "! $msg" -ForegroundColor Yellow }
function Write-Err { param($msg) Write-Error "$msg"; throw "Installation failed: $msg" }
# ---- Detect architecture ----
function Get-Arch {
$arch = [System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture
switch ($arch) {
"X64" { return "amd64" }
"Arm64" { return "arm64" }
default {
# Fallback for older PowerShell
if ($env:PROCESSOR_ARCHITECTURE -eq "AMD64") { return "amd64" }
if ($env:PROCESSOR_ARCHITECTURE -eq "ARM64") { return "arm64" }
Write-Err "Unsupported architecture: $arch"
}
}
}
# ---- Detect install directory ----
function Get-InstallDir {
if ($InstallDir) { return $InstallDir }
if ($env:INSTALL_DIR) { return $env:INSTALL_DIR }
# Default: %LOCALAPPDATA%\Programs\unarr
$dir = Join-Path $env:LOCALAPPDATA "Programs\unarr"
if (-not (Test-Path $dir)) {
New-Item -ItemType Directory -Path $dir -Force | Out-Null
}
return $dir
}
# ---- Get latest version ----
function Get-LatestVersion {
if ($Version) { return $Version.TrimStart("v") }
if ($env:VERSION) { return $env:VERSION.TrimStart("v") }
Write-Info "Checking latest version..."
try {
$release = Invoke-RestMethod "https://api.github.com/repos/$Repo/releases/latest"
return $release.tag_name.TrimStart("v")
} catch {
# Fallback: follow redirect
try {
$response = Invoke-WebRequest "https://github.com/$Repo/releases/latest" -MaximumRedirection 0 -ErrorAction SilentlyContinue
$location = $response.Headers.Location
if ($location -match "/v?(\d+\.\d+\.\d+)") {
return $Matches[1]
}
} catch {}
}
Write-Err "Could not determine latest version. Set `$env:VERSION='x.y.z' and retry."
}
# ---- Add to PATH ----
function Add-ToPath {
param($dir)
$currentPath = [Environment]::GetEnvironmentVariable("PATH", "User")
if ($currentPath -split ";" -contains $dir) { return }
Write-Info "Adding $dir to user PATH..."
[Environment]::SetEnvironmentVariable("PATH", "$currentPath;$dir", "User")
$env:PATH = "$env:PATH;$dir"
Write-Ok "Added to PATH (restart terminal for full effect)"
}
# ---- Install binary ----
function Install-Binary {
$ver = Get-LatestVersion
$arch = Get-Arch
$dir = Get-InstallDir
$archive = "unarr_${ver}_windows_${arch}.zip"
$url = "https://github.com/$Repo/releases/download/v${ver}/$archive"
Write-Info "Downloading unarr v$ver for windows/$arch..."
$tmpDir = Join-Path $env:TEMP "unarr-install-$(Get-Random)"
New-Item -ItemType Directory -Path $tmpDir -Force | Out-Null
try {
$zipPath = Join-Path $tmpDir $archive
Invoke-WebRequest -Uri $url -OutFile $zipPath -UseBasicParsing
Write-Info "Extracting..."
Expand-Archive -Path $zipPath -DestinationPath $tmpDir -Force
# Find binary
$binPath = Get-ChildItem -Path $tmpDir -Recurse -Filter "unarr.exe" | Select-Object -First 1
if (-not $binPath) {
Write-Err "Binary not found in archive"
}
Copy-Item $binPath.FullName (Join-Path $dir $Binary) -Force
Write-Ok "Installed unarr v$ver to $dir\$Binary"
Add-ToPath $dir
} finally {
Remove-Item -Recurse -Force $tmpDir -ErrorAction SilentlyContinue
}
}
# ---- Install Docker ----
function Install-Docker {
$dockerCmd = Get-Command docker -ErrorAction SilentlyContinue
if (-not $dockerCmd) {
Write-Err "Docker not found. Install Docker Desktop: https://docs.docker.com/desktop/install/windows/"
}
Write-Info "Pulling torrentclaw/unarr:latest..."
try {
docker pull torrentclaw/unarr:latest 2>$null
} catch {
Write-Info "Image not on Docker Hub, building from source..."
$gitCmd = Get-Command git -ErrorAction SilentlyContinue
if (-not $gitCmd) {
Write-Err "git not found. Install git or pull the image manually."
}
$tmpDir = Join-Path $env:TEMP "unarr-build-$(Get-Random)"
git clone --depth 1 "https://github.com/$Repo.git" $tmpDir
docker build -t torrentclaw/unarr:latest $tmpDir
Remove-Item -Recurse -Force $tmpDir -ErrorAction SilentlyContinue
}
Write-Ok "Docker image ready: torrentclaw/unarr:latest"
Write-Host ""
Write-Host "Quick start:" -ForegroundColor White
Write-Host ""
Write-Host " # 1. Create config directory"
Write-Host " mkdir `$env:APPDATA\unarr"
Write-Host ""
Write-Host " # 2. Run setup (interactive)"
Write-Host " docker run -it --rm -v `$env:APPDATA\unarr:/config torrentclaw/unarr init"
Write-Host ""
Write-Host " # 3. Start daemon"
Write-Host " docker run -d --name unarr --restart unless-stopped ``"
Write-Host " --read-only --memory 512m ``"
Write-Host " -v `$env:APPDATA\unarr:/config ``"
Write-Host " -v `$HOME\Media:/downloads ``"
Write-Host " torrentclaw/unarr"
Write-Host ""
}
# ---- Uninstall ----
function Uninstall-Unarr {
Write-Info "Uninstalling unarr..."
# Remove binary
$dir = Get-InstallDir
$binPath = Join-Path $dir $Binary
if (Test-Path $binPath) {
Remove-Item $binPath -Force
Write-Ok "Removed $binPath"
}
# Clean empty install dir
if ((Test-Path $dir) -and -not (Get-ChildItem $dir)) {
Remove-Item $dir -Force
}
# Remove Docker
$dockerCmd = Get-Command docker -ErrorAction SilentlyContinue
if ($dockerCmd) {
docker rm -f unarr 2>$null | Out-Null
docker rmi torrentclaw/unarr:latest 2>$null | Out-Null
Write-Ok "Removed Docker container and image"
}
Write-Ok "Uninstalled. Config remains at $env:APPDATA\unarr\ (delete manually if desired)."
exit
}
# ---- Interactive menu ----
function Show-Menu {
Write-Host ""
Write-Host " unarr Installer" -ForegroundColor White
Write-Host " ────────────────────────"
Write-Host ""
Write-Host " Detected: " -NoNewline
Write-Host "windows/$(Get-Arch)" -ForegroundColor Cyan
Write-Host ""
Write-Host " Install method:"
Write-Host ""
Write-Host " 1) " -NoNewline -ForegroundColor White
Write-Host "Binary — standalone .exe, no dependencies"
Write-Host " 2) " -NoNewline -ForegroundColor White
Write-Host "Docker — sandboxed, isolated filesystem access " -NoNewline
Write-Host "(recommended)" -ForegroundColor Green
Write-Host " u) " -NoNewline -ForegroundColor White
Write-Host "Uninstall"
Write-Host ""
$choice = Read-Host " Choice [1/2]"
switch ($choice) {
"1" { return "binary" }
"2" { return "docker" }
"u" { Uninstall-Unarr }
"U" { Uninstall-Unarr }
default { Write-Err "Invalid choice: $choice" }
}
}
# ---- Main ----
function Main {
# Resolve method
$m = if ($Method) { $Method }
elseif ($env:METHOD) { $env:METHOD }
else { Show-Menu }
Write-Host ""
switch ($m) {
"binary" {
Install-Binary
Write-Host ""
Write-Host " Run " -NoNewline
Write-Host "unarr init" -ForegroundColor White -NoNewline
Write-Host " to get started."
Write-Host ""
}
"docker" {
Install-Docker
}
default {
Write-Err "Unknown method: $m"
}
}
}
Main