-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinstall.ps1
More file actions
137 lines (113 loc) · 4.63 KB
/
install.ps1
File metadata and controls
137 lines (113 loc) · 4.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# Vix.cpp installer (Windows PowerShell)
# Usage:
# irm https://vixcpp.com/install.ps1 | iex
# Optional:
# $env:VIX_VERSION="v1.20.1"
# $env:VIX_INSTALL_DIR="$env:LOCALAPPDATA\Vix\bin"
# $env:VIX_REPO="vixcpp/vix"
$ErrorActionPreference = "Stop"
$ProgressPreference = "SilentlyContinue"
function Info($msg) { Write-Host "vix install: $msg" }
function Die($msg) { throw "vix install: $msg" }
$Repo = if ($env:VIX_REPO) { $env:VIX_REPO } else { "vixcpp/vix" }
$Version = if ($env:VIX_VERSION) { $env:VIX_VERSION } else { "latest" }
$InstallDir = if ($env:VIX_INSTALL_DIR) { $env:VIX_INSTALL_DIR } else { Join-Path $env:LOCALAPPDATA "Vix\bin" }
$BinName = "vix.exe"
function Resolve-LatestTag([string]$repo) {
# Robust way: call GitHub API (no auth needed for low volume)
$api = "https://api.github.com/repos/$repo/releases/latest"
try {
$resp = Invoke-RestMethod -Uri $api -Headers @{ "User-Agent" = "vix-installer" }
if (-not $resp.tag_name) { Die "could not resolve latest tag. Set VIX_VERSION=vX.Y.Z" }
return $resp.tag_name
} catch {
Die "could not resolve latest tag (GitHub API). Set VIX_VERSION=vX.Y.Z"
}
}
$Tag = if ($Version -eq "latest") { Resolve-LatestTag $Repo } else { $Version }
# Detect arch (prefer OS bitness + ARM check)
$archRaw = $env:PROCESSOR_ARCHITECTURE
$Arch = switch -Regex ($archRaw) {
"AMD64" { "x86_64"; break }
"^ARM" { "aarch64"; break }
default { Die "unsupported arch: $archRaw" }
}
$Asset = "vix-windows-$Arch.zip"
$BaseUrl = "https://github.com/$Repo/releases/download/$Tag"
$UrlBin = "$BaseUrl/$Asset"
$UrlSha = "$UrlBin.sha256"
Info "repo=$Repo version=$Tag arch=$Arch"
Info "install_dir=$InstallDir"
# Temp dir unique
$TmpDir = Join-Path ([System.IO.Path]::GetTempPath()) ("vix-" + [System.Guid]::NewGuid().ToString("N"))
New-Item -ItemType Directory -Force -Path $TmpDir | Out-Null
try {
$ZipPath = Join-Path $TmpDir $Asset
$ShaPath = Join-Path $TmpDir ($Asset + ".sha256")
Info "downloading: $UrlBin"
Invoke-WebRequest -Uri $UrlBin -OutFile $ZipPath
# SHA256 verification policy:
# - If sha256 file exists -> MUST verify and match.
# - If sha256 missing -> warn (optionally you can hard-fail; currently warn).
Info "trying sha256 verification..."
$shaOk = $false
try {
Invoke-WebRequest -Uri $UrlSha -OutFile $ShaPath
$first = (Get-Content -LiteralPath $ShaPath -TotalCount 1).Trim()
if (-not $first) { Die "invalid sha256 file" }
# Accept:
# 1) "<sha> file"
# 2) "SHA256 (file) = <sha>"
$expected = $null
if ($first -match "^[0-9a-fA-F]{64}") {
$expected = ($first -split "\s+")[0]
} elseif ($first -match "=\s*([0-9a-fA-F]{64})\s*$") {
$expected = $Matches[1]
}
if (-not $expected) { Die "invalid sha256 format" }
$actual = (Get-FileHash -Algorithm SHA256 -LiteralPath $ZipPath).Hash
if ($expected.ToLower() -ne $actual.ToLower()) { Die "sha256 mismatch" }
$shaOk = $true
Info "sha256 ok"
} catch {
Info "sha256 file not found (skipping)"
}
# Extract to temp first, then move only vix.exe (avoids zip path layout issues)
$ExtractDir = Join-Path $TmpDir "extract"
New-Item -ItemType Directory -Force -Path $ExtractDir | Out-Null
Expand-Archive -LiteralPath $ZipPath -DestinationPath $ExtractDir -Force
# Find vix.exe anywhere in archive
$ExeCandidate = Get-ChildItem -LiteralPath $ExtractDir -Recurse -File -Filter $BinName | Select-Object -First 1
if (-not $ExeCandidate) { Die "archive does not contain $BinName" }
New-Item -ItemType Directory -Force -Path $InstallDir | Out-Null
$Exe = Join-Path $InstallDir $BinName
Copy-Item -LiteralPath $ExeCandidate.FullName -Destination $Exe -Force
Info "installed to $Exe"
# Add to user PATH (idempotent + exact segment check)
$userPath = [Environment]::GetEnvironmentVariable("Path", "User")
if (-not $userPath) { $userPath = "" }
$segments = $userPath -split ";" | ForEach-Object { $_.Trim() } | Where-Object { $_ -ne "" }
$already = $false
foreach ($s in $segments) {
if ([string]::Equals($s.TrimEnd("\"), $InstallDir.TrimEnd("\"), [System.StringComparison]::OrdinalIgnoreCase)) {
$already = $true
break
}
}
if (-not $already) {
$newPath = ($segments + $InstallDir) -join ";"
[Environment]::SetEnvironmentVariable("Path", $newPath, "User")
Info "added to PATH (restart your terminal)"
} else {
Info "PATH already contains install_dir"
}
# Quick check
try {
$ver = & $Exe --version 2>$null
if ($ver) { Info "version: $ver" }
} catch { }
Info "done"
}
finally {
Remove-Item -LiteralPath $TmpDir -Recurse -Force -ErrorAction SilentlyContinue | Out-Null
}