Files
dotfiles/.chezmoiscripts/run_onchange_windows_install-packages.ps1.tmpl
T

143 lines
4.9 KiB
Cheetah

#!/usr/bin/env pwsh
# run_onchange_windows_install-packages.ps1.tmpl
# Installs all packages from packages/windows.json via winget.
# This script re-runs whenever packages/windows.json changes.
#
# Hash of packages file (forces re-run on change):
# {{ include "packages/windows.json" | sha256sum }}
$ErrorActionPreference = "Continue"
Write-Host "==> Installing packages via winget..." -ForegroundColor Cyan
# Use the chezmoi source packages file directly
$sourcePackages = "{{ .chezmoi.sourceDir }}/packages/windows.json"
$sourcePackages = [System.IO.Path]::GetFullPath($sourcePackages)
if (-not (Test-Path $sourcePackages)) {
Write-Warning "packages/windows.json not found at: $sourcePackages"
exit 1
}
$packageList = Get-Content $sourcePackages -Raw | ConvertFrom-Json
$packages = $packageList.Sources[0].Packages
$total = $packages.Count
$installed = 0
$skipped = 0
$failed = 0
foreach ($pkg in $packages) {
$id = $pkg.PackageIdentifier
Write-Host " Checking $id..." -NoNewline
# Check if already installed
$check = winget list --id $id --exact --accept-source-agreements 2>$null | Select-String $id
if ($check) {
Write-Host " already installed" -ForegroundColor DarkGray
$skipped++
continue
}
# Install
Write-Host " installing..." -NoNewline
$result = winget install --id $id --exact --silent --accept-package-agreements --accept-source-agreements 2>&1
if ($LASTEXITCODE -eq 0) {
Write-Host " done" -ForegroundColor Green
$installed++
} else {
Write-Host " FAILED (exit $LASTEXITCODE)" -ForegroundColor Red
$failed++
}
}
Write-Host ""
Write-Host "==> Package install complete: $installed installed, $skipped already present, $failed failed" -ForegroundColor Cyan
# =============================================================================
# Manual installs — tools not available on winget
# =============================================================================
$LocalBin = Join-Path $env:USERPROFILE ".local\bin"
if (-not (Test-Path $LocalBin)) {
New-Item -ItemType Directory -Force $LocalBin | Out-Null
}
# Ensure ~/.local/bin is in the user PATH
$userPath = [System.Environment]::GetEnvironmentVariable("PATH", "User")
if ($userPath -notlike "*$LocalBin*") {
[System.Environment]::SetEnvironmentVariable("PATH", "$userPath;$LocalBin", "User")
$env:PATH = "$env:PATH;$LocalBin"
Write-Host " Added $LocalBin to user PATH." -ForegroundColor Green
}
function Install-GitHubBinary {
param(
[string]$Name,
[string]$Repo,
[string]$AssetPattern,
[string]$BinaryName = "$Name.exe"
)
$BinPath = Join-Path $LocalBin $BinaryName
if (Test-Path $BinPath) {
Write-Host " $Name already installed" -ForegroundColor DarkGray
return
}
Write-Host " Installing $Name..." -NoNewline
try {
$release = Invoke-RestMethod "https://api.github.com/repos/$Repo/releases/latest"
$asset = $release.assets | Where-Object { $_.name -like $AssetPattern } | Select-Object -First 1
if (-not $asset) { throw "No matching asset found for pattern: $AssetPattern" }
$tmpZip = Join-Path $env:TEMP "$Name-$($release.tag_name).zip"
$tmpDir = Join-Path $env:TEMP "$Name-$($release.tag_name)"
Invoke-WebRequest -Uri $asset.browser_download_url -OutFile $tmpZip -UseBasicParsing
Expand-Archive -Path $tmpZip -DestinationPath $tmpDir -Force
$exe = Get-ChildItem -Recurse $tmpDir -Filter $BinaryName | Select-Object -First 1
Copy-Item $exe.FullName $BinPath
Remove-Item $tmpZip -Force
Remove-Item $tmpDir -Recurse -Force
Write-Host " done" -ForegroundColor Green
} catch {
Write-Host " FAILED: $_" -ForegroundColor Red
}
}
Write-Host ""
Write-Host "==> Installing manual (non-winget) packages..." -ForegroundColor Cyan
# watchexec — https://github.com/watchexec/watchexec
Install-GitHubBinary -Name "watchexec" -Repo "watchexec/watchexec" -AssetPattern "*x86_64-pc-windows-msvc.zip"
# Antigravity CLI — https://antigravity.google/cli/
if (-not (Get-Command antigravity -ErrorAction SilentlyContinue)) {
Write-Host " Installing Antigravity CLI..." -NoNewline
try {
irm https://antigravity.google/cli/install.ps1 | iex
Write-Host " done" -ForegroundColor Green
} catch {
Write-Host " FAILED: $_" -ForegroundColor Red
}
} else {
Write-Host " Antigravity CLI already installed" -ForegroundColor DarkGray
}
# termato — https://github.com/StevanFreeborn/termato
if (-not (Get-Command termato -ErrorAction SilentlyContinue)) {
Write-Host " Installing termato..." -NoNewline
try {
irm https://github.com/StevanFreeborn/termato/releases/latest/download/termato-installer.ps1 | iex
Write-Host " done" -ForegroundColor Green
} catch {
Write-Host " FAILED: $_" -ForegroundColor Red
}
} else {
Write-Host " termato already installed" -ForegroundColor DarkGray
}