Repository navigation
Expand file tree
/
Copy pathinstall.ps1
More file actions
145 lines (132 loc) · 6.45 KB
/
Copy pathinstall.ps1
File metadata and controls
145 lines (132 loc) · 6.45 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
138
139
140
141
142
143
144
145
[CmdletBinding()]
param(
[string]$Version = $env:AGENTVIEW_VERSION,
[string]$InstallDir = $env:AGENTVIEW_INSTALL_DIR,
[string]$Repo = $(if ($env:AGENTVIEW_REPO) { $env:AGENTVIEW_REPO } else { "moritzWa/agentview" }),
[string]$ReleaseBaseUrl = $env:AGENTVIEW_RELEASE_BASE_URL,
[int]$WaitForProcessId = 0,
[string]$PreviousVersion = "",
[switch]$CleanupStaging,
[switch]$SkipPathUpdate
)
$ErrorActionPreference = "Stop"
Set-StrictMode -Version 2.0
function Write-AgentviewMessage([string]$Message) {
Write-Host "agentview: $Message"
}
function Copy-OrDownload([string]$Source, [string]$Destination) {
if (Test-Path -LiteralPath $Source) {
Copy-Item -LiteralPath $Source -Destination $Destination -Force
} else {
Invoke-WebRequest -UseBasicParsing -Uri $Source -OutFile $Destination
}
}
function Install-AgentviewAlias([string]$Source, [string]$Destination) {
if (Test-Path -LiteralPath $Destination) {
$reported = ""
try { $reported = (& $Destination --version 2>$null | Out-String).Trim() } catch {}
if ($reported -notmatch '^agentview [0-9]+\.[0-9]+\.[0-9]+$') {
Write-AgentviewMessage "left unrelated existing command in place: $Destination"
return
}
}
Copy-Item -LiteralPath $Source -Destination $Destination -Force
}
if ($WaitForProcessId -gt 0) {
$running = Get-Process -Id $WaitForProcessId -ErrorAction SilentlyContinue
if ($running) {
Write-AgentviewMessage "waiting for the running agentview process to exit"
$running.WaitForExit()
}
}
if (-not $Version) { $Version = "latest" }
if (-not $InstallDir) {
$base = if ($env:LOCALAPPDATA) { $env:LOCALAPPDATA } else { Join-Path $env:USERPROFILE "AppData\Local" }
$InstallDir = Join-Path $base "Programs\agentview\bin"
}
if ($Repo -notmatch '^[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+$') {
throw "repository must have the form OWNER/REPO"
}
$architecture = [System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture.ToString()
switch ($architecture) {
"X64" { $target = "x86_64-pc-windows-msvc" }
default { throw "no native Windows release is available for $architecture yet; use Windows x64 or WSL 2" }
}
if ($Version -eq "latest") {
$headers = @{ "Accept" = "application/vnd.github+json" }
if ($env:GH_TOKEN) { $headers["Authorization"] = "Bearer $($env:GH_TOKEN)" }
$release = Invoke-RestMethod -Headers $headers -Uri "https://api.github.com/repos/$Repo/releases/latest"
$tag = [string]$release.tag_name
} else {
$tag = "v$($Version.TrimStart('v'))"
}
if ($tag -notmatch '^v[0-9]+\.[0-9]+\.[0-9]+$') {
throw "release version must have the form MAJOR.MINOR.PATCH (received: $tag)"
}
$resolvedVersion = $tag.Substring(1)
$stem = "agentview-$resolvedVersion-$target"
$archive = "$stem.zip"
$checksum = "$archive.sha256"
$temporary = Join-Path ([System.IO.Path]::GetTempPath()) ("agentview-install-" + [guid]::NewGuid())
$staged = Join-Path $InstallDir (".agentview.install." + $PID + ".exe")
try {
New-Item -ItemType Directory -Path $temporary -Force | Out-Null
if ($ReleaseBaseUrl) {
$base = $ReleaseBaseUrl.TrimEnd('/', '\') + "\$tag"
if ($ReleaseBaseUrl -match '^https?://') { $base = $ReleaseBaseUrl.TrimEnd('/') + "/$tag" }
} else {
$base = "https://github.com/$Repo/releases/download/$tag"
}
Write-AgentviewMessage "downloading $tag for $target"
Copy-OrDownload "$base/$archive" (Join-Path $temporary $archive)
Copy-OrDownload "$base/$checksum" (Join-Path $temporary $checksum)
$expected = ((Get-Content -LiteralPath (Join-Path $temporary $checksum) -TotalCount 1) -split '\s+')[0]
if ($expected -notmatch '^[0-9a-fA-F]{64}$') { throw "release checksum file is malformed" }
$actual = (Get-FileHash -Algorithm SHA256 -LiteralPath (Join-Path $temporary $archive)).Hash
if ($actual -ne $expected) { throw "release checksum verification failed" }
Expand-Archive -LiteralPath (Join-Path $temporary $archive) -DestinationPath $temporary -Force
$binary = Join-Path (Join-Path $temporary $stem) "agentview.exe"
if (-not (Test-Path -LiteralPath $binary -PathType Leaf)) {
throw "release archive does not contain $stem/agentview.exe"
}
New-Item -ItemType Directory -Path $InstallDir -Force | Out-Null
Copy-Item -LiteralPath $binary -Destination $staged -Force
$reported = (& $staged --version | Out-String).Trim()
if ($reported -ne "agentview $resolvedVersion") {
throw "downloaded binary reported an unexpected version: $reported"
}
Move-Item -LiteralPath $staged -Destination (Join-Path $InstallDir "agentview.exe") -Force
$canonical = Join-Path $InstallDir "agentview.exe"
Install-AgentviewAlias $canonical (Join-Path $InstallDir "av.exe")
if (-not $SkipPathUpdate) {
$userPath = [Environment]::GetEnvironmentVariable("Path", "User")
$parts = @($userPath -split ';' | Where-Object { $_ })
if ($parts -notcontains $InstallDir) {
[Environment]::SetEnvironmentVariable("Path", (($parts + $InstallDir) -join ';'), "User")
}
if (($env:Path -split ';') -notcontains $InstallDir) { $env:Path = "$InstallDir;$env:Path" }
}
Write-AgentviewMessage "installed agentview $resolvedVersion to $InstallDir\agentview.exe"
Write-AgentviewMessage "installed shorthand: av"
Write-AgentviewMessage "open a new terminal, then run: agentview (or av)"
if ($PreviousVersion) {
if ($PreviousVersion -eq $resolvedVersion) {
Write-AgentviewMessage "agentview is already up to date at $resolvedVersion"
} else {
Write-AgentviewMessage "updated agentview from $PreviousVersion to $resolvedVersion"
}
}
} finally {
Remove-Item -LiteralPath $staged -Force -ErrorAction SilentlyContinue
Remove-Item -LiteralPath $temporary -Recurse -Force -ErrorAction SilentlyContinue
if ($CleanupStaging -and $PSCommandPath) {
$stagingDirectory = Split-Path -Parent $PSCommandPath
$stagingParent = Split-Path -Parent $stagingDirectory
$temporaryRoot = [System.IO.Path]::GetTempPath().TrimEnd('\', '/')
$stagingName = Split-Path -Leaf $stagingDirectory
if ($stagingParent.TrimEnd('\', '/') -eq $temporaryRoot -and $stagingName -match '^agentview-update-[0-9]+-[0-9]+$') {
Remove-Item -LiteralPath $PSCommandPath -Force -ErrorAction SilentlyContinue
Remove-Item -LiteralPath $stagingDirectory -Force -ErrorAction SilentlyContinue
}
}
}