Skip to content

Commit 1db79cf

Browse files
committed
Update install
1 parent 60bd76b commit 1db79cf

File tree

2 files changed

+179
-152
lines changed

2 files changed

+179
-152
lines changed

install.ps1

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ $Repo = if ($env:VIX_REPO) { $env:VIX_REPO } else { "vixcpp/
1616
$Version = if ($env:VIX_VERSION) { $env:VIX_VERSION } else { "latest" }
1717
$InstallDir = if ($env:VIX_INSTALL_DIR) { $env:VIX_INSTALL_DIR } else { Join-Path $env:LOCALAPPDATA "Vix\bin" }
1818
$BinName = "vix.exe"
19+
$MiniSignPubKey = "RWSIfpPSznK9A1gWUc8Eg2iXXQwU5d9BYuQNKGOcoujAF2stPu5rKFjQ"
1920

2021
function Resolve-LatestTag([string]$repo) {
2122
# Robust way: call GitHub API (no auth needed for low volume)
@@ -43,6 +44,8 @@ $Asset = "vix-windows-$Arch.zip"
4344
$BaseUrl = "https://github.com/$Repo/releases/download/$Tag"
4445
$UrlBin = "$BaseUrl/$Asset"
4546
$UrlSha = "$UrlBin.sha256"
47+
$UrlMiniSig = "$UrlBin.minisig"
48+
$SigPath = Join-Path $TmpDir ($Asset + ".minisig")
4649

4750
Info "repo=$Repo version=$Tag arch=$Arch"
4851
Info "install_dir=$InstallDir"
@@ -84,6 +87,23 @@ try {
8487

8588
$shaOk = $true
8689
Info "sha256 ok"
90+
91+
Info "trying minisign verification..."
92+
try {
93+
Invoke-WebRequest -Uri $UrlMiniSig -OutFile $SigPath
94+
95+
$mini = Get-Command minisign -ErrorAction SilentlyContinue
96+
if (-not $mini) {
97+
Die "minisig is published but minisign is not installed (install minisign or use a release without minisig)"
98+
}
99+
100+
# minisign on Windows supports -V -m <file> -x <sig> -P <pubkey>
101+
& minisign -V -m $ZipPath -x $SigPath -P $MiniSignPubKey | Out-Null
102+
103+
Info "minisign ok"
104+
} catch {
105+
Info "minisig not found (skipping)"
106+
}
87107
} catch {
88108
Info "sha256 file not found (skipping)"
89109
}

install.sh

Lines changed: 159 additions & 152 deletions
Original file line numberDiff line numberDiff line change
@@ -1,156 +1,163 @@
1-
#!/usr/bin/env sh
2-
set -eu
3-
4-
# minisign public key (ONLY the base64 key, without the comment line)
5-
MINISIGN_PUBKEY="RWTB+/RzT24X6uPqrPGKrqODmbchU4N1G00fWzQSUc+qkz7pBUnEys58"
6-
7-
REPO="${VIX_REPO:-vixcpp/vix}"
8-
VERSION="${VIX_VERSION:-latest}" # "latest" or "v1.20.1"
9-
INSTALL_DIR="${VIX_INSTALL_DIR:-$HOME/.local/bin}"
10-
BIN_NAME="vix"
11-
12-
die() { printf "vix install: %s\n" "$*" >&2; exit 1; }
13-
info() { printf "vix install: %s\n" "$*" >&2; }
14-
15-
have() { command -v "$1" >/dev/null 2>&1; }
16-
need_cmd() { have "$1" || die "missing dependency: $1"; }
17-
18-
fetch() {
19-
url="$1"
20-
out="$2"
21-
if have curl; then
22-
curl -fsSL "$url" -o "$out" >/dev/null 2>&1
23-
elif have wget; then
24-
wget -qO "$out" "$url" >/dev/null 2>&1
25-
else
26-
die "need curl or wget"
27-
fi
1+
# Vix.cpp installer (Windows PowerShell)
2+
# Usage:
3+
# irm https://vixcpp.com/install.ps1 | iex
4+
# Optional:
5+
# $env:VIX_VERSION="v1.20.1"
6+
# $env:VIX_INSTALL_DIR="$env:LOCALAPPDATA\Vix\bin"
7+
# $env:VIX_REPO="vixcpp/vix"
8+
9+
$ErrorActionPreference = "Stop"
10+
$ProgressPreference = "SilentlyContinue"
11+
12+
function Info($msg) { Write-Host "vix install: $msg" }
13+
function Die($msg) { throw "vix install: $msg" }
14+
15+
$Repo = if ($env:VIX_REPO) { $env:VIX_REPO } else { "vixcpp/vix" }
16+
$Version = if ($env:VIX_VERSION) { $env:VIX_VERSION } else { "latest" }
17+
$InstallDir = if ($env:VIX_INSTALL_DIR) { $env:VIX_INSTALL_DIR } else { Join-Path $env:LOCALAPPDATA "Vix\bin" }
18+
$BinName = "vix.exe"
19+
20+
# minisign public key (base64 only)
21+
$MiniSignPubKey = "RWSIfpPSznK9A1gWUc8Eg2iXXQwU5d9BYuQNKGOcoujAF2stPu5rKFjQ"
22+
23+
function Resolve-LatestTag([string]$repo) {
24+
$api = "https://api.github.com/repos/$repo/releases/latest"
25+
try {
26+
$resp = Invoke-RestMethod -Uri $api -Headers @{ "User-Agent" = "vix-installer" }
27+
if (-not $resp.tag_name) { Die "could not resolve latest tag. Set VIX_VERSION=vX.Y.Z" }
28+
return $resp.tag_name
29+
} catch {
30+
Die "could not resolve latest tag (GitHub API). Set VIX_VERSION=vX.Y.Z"
31+
}
2832
}
2933

30-
need_cmd uname
31-
need_cmd mktemp
32-
need_cmd tar
33-
34-
os="$(uname -s | tr '[:upper:]' '[:lower:]')"
35-
arch="$(uname -m)"
36-
37-
case "$os" in
38-
linux) OS="linux" ;;
39-
darwin) OS="macos" ;;
40-
*) die "unsupported OS: $os (only Linux/macOS supported by install.sh)" ;;
41-
esac
42-
43-
case "$arch" in
44-
x86_64|amd64) ARCH="x86_64" ;;
45-
arm64|aarch64) ARCH="aarch64" ;;
46-
*) die "unsupported CPU arch: $arch" ;;
47-
esac
48-
49-
TMP_DIR="$(mktemp -d 2>/dev/null || mktemp -d -t vix)"
50-
cleanup() { rm -rf "$TMP_DIR"; }
51-
trap cleanup EXIT INT TERM
52-
53-
resolve_version() {
54-
if [ "$VERSION" = "latest" ]; then
55-
have curl || die "curl is required to resolve latest (or set VIX_VERSION=vX.Y.Z)"
56-
final="$(curl -fsSLI -o /dev/null -w '%{url_effective}' "https://github.com/$REPO/releases/latest")"
57-
tag="${final##*/}"
58-
[ -n "$tag" ] || die "could not resolve latest version"
59-
printf "%s" "$tag"
60-
else
61-
printf "%s" "$VERSION"
62-
fi
34+
$Tag = if ($Version -eq "latest") { Resolve-LatestTag $Repo } else { $Version }
35+
36+
# Detect arch
37+
$archRaw = $env:PROCESSOR_ARCHITECTURE
38+
$Arch = switch -Regex ($archRaw) {
39+
"AMD64" { "x86_64"; break }
40+
"^ARM" { "aarch64"; break }
41+
default { Die "unsupported arch: $archRaw" }
6342
}
6443

65-
TAG="$(resolve_version)"
66-
info "repo=$REPO version=$TAG os=$OS arch=$ARCH"
67-
68-
ASSET="vix-${OS}-${ARCH}.tar.gz"
69-
BASE_URL="https://github.com/${REPO}/releases/download/${TAG}"
70-
URL_BIN="${BASE_URL}/${ASSET}"
71-
URL_SHA="${URL_BIN}.sha256"
72-
URL_MINISIG="${URL_BIN}.minisig"
73-
74-
bin_tgz="${TMP_DIR}/${ASSET}"
75-
sha_file="${TMP_DIR}/${ASSET}.sha256"
76-
sig_file="${TMP_DIR}/${ASSET}.minisig"
77-
78-
info "downloading: $URL_BIN"
79-
fetch "$URL_BIN" "$bin_tgz" || die "download failed"
80-
81-
# ---- Verification policy ----
82-
# Require at least one verification method (sha256 or minisign).
83-
have_sha=0
84-
have_sig=0
85-
86-
info "trying sha256 verification..."
87-
if fetch "$URL_SHA" "$sha_file"; then
88-
have_sha=1
89-
if ! have sha256sum && ! have shasum; then
90-
die "need sha256sum (Linux) or shasum (macOS) for verification"
91-
fi
92-
93-
# support both formats:
94-
# 1) "<sha> <file>"
95-
# 2) "SHA256 (file) = <sha>"
96-
expected="$(
97-
awk '
98-
/^[0-9a-fA-F]{64}/ { print $1; exit }
99-
/^SHA256 \(/ { print $NF; exit }
100-
' "$sha_file"
101-
)"
102-
[ -n "$expected" ] || die "invalid sha256 file"
103-
104-
if have sha256sum; then
105-
actual="$(sha256sum "$bin_tgz" | awk '{print $1}')"
106-
else
107-
actual="$(shasum -a 256 "$bin_tgz" | awk '{print $1}')"
108-
fi
109-
110-
[ "$expected" = "$actual" ] || die "sha256 mismatch"
111-
info "sha256 ok"
112-
else
113-
info "sha256 file not found"
114-
fi
115-
116-
info "trying minisign verification..."
117-
if fetch "$URL_MINISIG" "$sig_file"; then
118-
have_sig=1
119-
have minisign || die "minisig is published but minisign is not installed"
120-
minisign -Vm "$bin_tgz" -P "$MINISIGN_PUBKEY" >/dev/null 2>&1 \
121-
|| die "minisign verification failed"
122-
info "minisign ok"
123-
else
124-
info "minisig not found"
125-
fi
126-
127-
if [ "$have_sha" -eq 0 ] && [ "$have_sig" -eq 0 ]; then
128-
die "no verification file found (.sha256 or .minisig). refusing to install."
129-
fi
130-
131-
# Extract and install
132-
mkdir -p "$INSTALL_DIR"
133-
tar -xzf "$bin_tgz" -C "$TMP_DIR"
134-
[ -f "${TMP_DIR}/${BIN_NAME}" ] || die "archive does not contain '${BIN_NAME}'"
135-
136-
chmod +x "${TMP_DIR}/${BIN_NAME}"
137-
dest="${INSTALL_DIR}/${BIN_NAME}"
138-
info "installing to: $dest"
139-
mv -f "${TMP_DIR}/${BIN_NAME}" "$dest"
140-
141-
if "$dest" --version >/dev/null 2>&1; then
142-
info "installed: $("$dest" --version 2>/dev/null || true)"
143-
else
144-
info "installed, but running 'vix --version' failed (PATH or runtime issue)"
145-
fi
146-
147-
case ":$PATH:" in
148-
*":$INSTALL_DIR:"*) : ;;
149-
*)
150-
info "NOTE: '$INSTALL_DIR' is not in your PATH."
151-
info "Add this to your shell config:"
152-
info " export PATH=\"$INSTALL_DIR:\$PATH\""
153-
;;
154-
esac
155-
156-
info "done"
44+
$Asset = "vix-windows-$Arch.zip"
45+
$BaseUrl = "https://github.com/$Repo/releases/download/$Tag"
46+
$UrlBin = "$BaseUrl/$Asset"
47+
$UrlSha = "$UrlBin.sha256"
48+
$UrlMiniSig = "$UrlBin.minisig"
49+
50+
Info "repo=$Repo version=$Tag arch=$Arch"
51+
Info "install_dir=$InstallDir"
52+
53+
# Temp dir unique
54+
$TmpDir = Join-Path ([System.IO.Path]::GetTempPath()) ("vix-" + [System.Guid]::NewGuid().ToString("N"))
55+
New-Item -ItemType Directory -Force -Path $TmpDir | Out-Null
56+
57+
try {
58+
$ZipPath = Join-Path $TmpDir $Asset
59+
$ShaPath = Join-Path $TmpDir ($Asset + ".sha256")
60+
$SigPath = Join-Path $TmpDir ($Asset + ".minisig")
61+
62+
Info "downloading: $UrlBin"
63+
Invoke-WebRequest -Uri $UrlBin -OutFile $ZipPath
64+
65+
# Require at least one verification method (sha256 or minisign)
66+
$haveSha = $false
67+
$haveSig = $false
68+
69+
# --- SHA256 verification ---
70+
Info "trying sha256 verification..."
71+
try {
72+
Invoke-WebRequest -Uri $UrlSha -OutFile $ShaPath
73+
74+
$first = (Get-Content -LiteralPath $ShaPath -TotalCount 1).Trim()
75+
if (-not $first) { Die "invalid sha256 file" }
76+
77+
# Accept:
78+
# 1) "<sha> file"
79+
# 2) "SHA256 (file) = <sha>"
80+
$expected = $null
81+
if ($first -match "^[0-9a-fA-F]{64}") {
82+
$expected = ($first -split "\s+")[0]
83+
} elseif ($first -match "=\s*([0-9a-fA-F]{64})\s*$") {
84+
$expected = $Matches[1]
85+
}
86+
if (-not $expected) { Die "invalid sha256 format" }
87+
88+
$actual = (Get-FileHash -Algorithm SHA256 -LiteralPath $ZipPath).Hash
89+
if ($expected.ToLower() -ne $actual.ToLower()) { Die "sha256 mismatch" }
90+
91+
$haveSha = $true
92+
Info "sha256 ok"
93+
} catch {
94+
Info "sha256 file not found (skipping)"
95+
}
96+
97+
# --- minisign verification (if minisig exists) ---
98+
Info "trying minisign verification..."
99+
try {
100+
Invoke-WebRequest -Uri $UrlMiniSig -OutFile $SigPath
101+
$haveSig = $true
102+
103+
$mini = Get-Command minisign -ErrorAction SilentlyContinue
104+
if (-not $mini) {
105+
Die "minisig is published but minisign is not installed (install minisign or use sha256-only verification)"
106+
}
107+
108+
& minisign -V -m $ZipPath -x $SigPath -P $MiniSignPubKey | Out-Null
109+
Info "minisign ok"
110+
} catch {
111+
Info "minisig not found (skipping)"
112+
}
113+
114+
if (-not $haveSha -and -not $haveSig) {
115+
Die "no verification file found (.sha256 or .minisig). refusing to install."
116+
}
117+
118+
# Extract to temp first, then move only vix.exe
119+
$ExtractDir = Join-Path $TmpDir "extract"
120+
New-Item -ItemType Directory -Force -Path $ExtractDir | Out-Null
121+
Expand-Archive -LiteralPath $ZipPath -DestinationPath $ExtractDir -Force
122+
123+
$ExeCandidate = Get-ChildItem -LiteralPath $ExtractDir -Recurse -File -Filter $BinName | Select-Object -First 1
124+
if (-not $ExeCandidate) { Die "archive does not contain $BinName" }
125+
126+
New-Item -ItemType Directory -Force -Path $InstallDir | Out-Null
127+
$Exe = Join-Path $InstallDir $BinName
128+
Copy-Item -LiteralPath $ExeCandidate.FullName -Destination $Exe -Force
129+
130+
Info "installed to $Exe"
131+
132+
# Add to user PATH (idempotent)
133+
$userPath = [Environment]::GetEnvironmentVariable("Path", "User")
134+
if (-not $userPath) { $userPath = "" }
135+
136+
$segments = $userPath -split ";" | ForEach-Object { $_.Trim() } | Where-Object { $_ -ne "" }
137+
$already = $false
138+
foreach ($s in $segments) {
139+
if ([string]::Equals($s.TrimEnd("\"), $InstallDir.TrimEnd("\"), [System.StringComparison]::OrdinalIgnoreCase)) {
140+
$already = $true
141+
break
142+
}
143+
}
144+
145+
if (-not $already) {
146+
$newPath = ($segments + $InstallDir) -join ";"
147+
[Environment]::SetEnvironmentVariable("Path", $newPath, "User")
148+
Info "added to PATH (restart your terminal)"
149+
} else {
150+
Info "PATH already contains install_dir"
151+
}
152+
153+
# Quick check
154+
try {
155+
$ver = & $Exe --version 2>$null
156+
if ($ver) { Info "version: $ver" }
157+
} catch { }
158+
159+
Info "done"
160+
}
161+
finally {
162+
Remove-Item -LiteralPath $TmpDir -Recurse -Force -ErrorAction SilentlyContinue | Out-Null
163+
}

0 commit comments

Comments
 (0)