110 lines
4.1 KiB
PowerShell
110 lines
4.1 KiB
PowerShell
|
|
[CmdletBinding()]
|
||
|
|
param(
|
||
|
|
[Parameter(Mandatory = $true)]
|
||
|
|
[ValidatePattern('^v[0-9][0-9A-Za-z._-]*$')]
|
||
|
|
[string]$Version,
|
||
|
|
|
||
|
|
[string]$InstallDir = $(
|
||
|
|
if ($env:GETH_INSTALL_DIR) { $env:GETH_INSTALL_DIR }
|
||
|
|
else { Join-Path $env:LOCALAPPDATA 'Programs\geth\bin' }
|
||
|
|
),
|
||
|
|
|
||
|
|
[string]$ReleaseBaseUrl = $(
|
||
|
|
if ($env:GETH_RELEASE_BASE_URL) { $env:GETH_RELEASE_BASE_URL }
|
||
|
|
else { 'https://forge.tionis.dev/eric/geth/releases/download' }
|
||
|
|
),
|
||
|
|
|
||
|
|
[string]$ArchivePath,
|
||
|
|
|
||
|
|
[string]$ChecksumPath,
|
||
|
|
|
||
|
|
[switch]$NoModifyPath,
|
||
|
|
|
||
|
|
[switch]$PrintAsset
|
||
|
|
)
|
||
|
|
|
||
|
|
$ErrorActionPreference = 'Stop'
|
||
|
|
Set-StrictMode -Version Latest
|
||
|
|
|
||
|
|
if (-not [Environment]::Is64BitOperatingSystem) {
|
||
|
|
throw 'No geth release artifact is available for 32-bit Windows.'
|
||
|
|
}
|
||
|
|
|
||
|
|
$asset = "geth-$Version-windows-x86_64.zip"
|
||
|
|
if ($PrintAsset) {
|
||
|
|
Write-Output $asset
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
$releaseBase = $ReleaseBaseUrl.TrimEnd('/')
|
||
|
|
$url = "$releaseBase/$Version/$asset"
|
||
|
|
$tempDir = Join-Path ([IO.Path]::GetTempPath()) ("geth-install-" + [Guid]::NewGuid())
|
||
|
|
$extractDir = Join-Path $tempDir 'extract'
|
||
|
|
|
||
|
|
try {
|
||
|
|
New-Item -ItemType Directory -Force -Path $tempDir, $extractDir | Out-Null
|
||
|
|
if ($ArchivePath) {
|
||
|
|
$archive = (Resolve-Path -LiteralPath $ArchivePath).Path
|
||
|
|
$checksumCandidate = if ($ChecksumPath) { $ChecksumPath } else { "$ArchivePath.sha256" }
|
||
|
|
$checksum = (Resolve-Path -LiteralPath $checksumCandidate).Path
|
||
|
|
Write-Host "using local archive $archive"
|
||
|
|
} else {
|
||
|
|
if ($ChecksumPath) { throw '-ChecksumPath requires -ArchivePath.' }
|
||
|
|
if (([Uri]$url).Scheme -ne 'https') { throw 'Release downloads require an HTTPS base URL.' }
|
||
|
|
$archive = Join-Path $tempDir $asset
|
||
|
|
$checksum = "$archive.sha256"
|
||
|
|
Write-Host "downloading $url"
|
||
|
|
Invoke-WebRequest -Uri $url -OutFile $archive
|
||
|
|
Invoke-WebRequest -Uri "$url.sha256" -OutFile $checksum
|
||
|
|
}
|
||
|
|
|
||
|
|
$expected = ((Get-Content -LiteralPath $checksum -Raw).Trim() -split '\s+')[0].ToLowerInvariant()
|
||
|
|
if ($expected -notmatch '^[0-9a-f]{64}$') {
|
||
|
|
throw "Invalid SHA-256 file for $asset."
|
||
|
|
}
|
||
|
|
$actual = (Get-FileHash -LiteralPath $archive -Algorithm SHA256).Hash.ToLowerInvariant()
|
||
|
|
if ($actual -ne $expected) {
|
||
|
|
throw "Checksum mismatch for $asset."
|
||
|
|
}
|
||
|
|
Write-Host "verified SHA-256: $actual"
|
||
|
|
|
||
|
|
Expand-Archive -LiteralPath $archive -DestinationPath $extractDir -Force
|
||
|
|
$sourceBinary = Join-Path $extractDir 'geth.exe'
|
||
|
|
if (-not (Test-Path -LiteralPath $sourceBinary -PathType Leaf)) {
|
||
|
|
throw 'Archive does not contain geth.exe.'
|
||
|
|
}
|
||
|
|
|
||
|
|
New-Item -ItemType Directory -Force -Path $InstallDir | Out-Null
|
||
|
|
$destination = Join-Path $InstallDir 'geth.exe'
|
||
|
|
$staged = Join-Path $InstallDir ('.geth.install.' + [Guid]::NewGuid() + '.exe')
|
||
|
|
try {
|
||
|
|
Copy-Item -LiteralPath $sourceBinary -Destination $staged
|
||
|
|
Move-Item -LiteralPath $staged -Destination $destination -Force
|
||
|
|
} catch {
|
||
|
|
Remove-Item -LiteralPath $staged -Force -ErrorAction SilentlyContinue
|
||
|
|
throw "Could not replace $destination. Stop the daemon with 'geth daemon stop' and retry. $($_.Exception.Message)"
|
||
|
|
}
|
||
|
|
|
||
|
|
if (-not $NoModifyPath) {
|
||
|
|
$userPath = [Environment]::GetEnvironmentVariable('Path', 'User')
|
||
|
|
$pathParts = @($userPath -split ';' | Where-Object { $_ })
|
||
|
|
if ($pathParts -notcontains $InstallDir) {
|
||
|
|
$newUserPath = (@($pathParts) + $InstallDir) -join ';'
|
||
|
|
try {
|
||
|
|
[Environment]::SetEnvironmentVariable('Path', $newUserPath, 'User')
|
||
|
|
Write-Host "added $InstallDir to the current user's PATH; open a new terminal to use it"
|
||
|
|
} catch {
|
||
|
|
Write-Warning "Could not update the user PATH. Add this directory manually: $InstallDir"
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
Write-Host "$InstallDir is already on the current user's PATH"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
Write-Host "installed geth to $destination"
|
||
|
|
Write-Host "the daemon was not started; run 'geth daemon install' when ready"
|
||
|
|
} finally {
|
||
|
|
if (Test-Path -LiteralPath $tempDir) {
|
||
|
|
Remove-Item -LiteralPath $tempDir -Recurse -Force
|
||
|
|
}
|
||
|
|
}
|