194 lines
7.2 KiB
Plaintext
194 lines
7.2 KiB
Plaintext
# Licensed under the MIT license
|
|
# <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
|
|
# option. This file may not be copied, modified, or distributed
|
|
# except according to those terms.
|
|
|
|
# This is just a little script that can be downloaded from the internet to
|
|
# install an app. It downloads the tarball from artifact_download_url,
|
|
# and extracts it to ~/.cargo/bin/
|
|
#
|
|
# In the future this script will gain extra features, but for now it's
|
|
# intentionally very simplistic to avoid shipping broken things.
|
|
|
|
param (
|
|
[Parameter(HelpMessage = 'The name of the App')]
|
|
[string]$app_name = 'adnix',
|
|
[Parameter(HelpMessage = 'The version of the App')]
|
|
[string]$app_version = '0.4.6',
|
|
[Parameter(HelpMessage = 'The URL of the directory where artifacts can be fetched from')]
|
|
[string]$artifact_download_url = 'https://github.com/msfjarvis/adnix-rs/releases/download/v0.4.6'
|
|
)
|
|
|
|
function Install-Binary($install_args) {
|
|
$old_erroractionpreference = $ErrorActionPreference
|
|
$ErrorActionPreference = 'stop'
|
|
|
|
Initialize-Environment
|
|
|
|
# Platform info injected by cargo-dist
|
|
$platforms = @{
|
|
"x86_64-pc-windows-msvc" = @{
|
|
"artifact_name" = "adnix-x86_64-pc-windows-msvc.zip"
|
|
"bins" = "adnix.exe"
|
|
"zip_ext" = ".zip"
|
|
}
|
|
}
|
|
|
|
$fetched = Download "$artifact_download_url" $platforms
|
|
# FIXME: add a flag that lets the user not do this step
|
|
Invoke-Installer $fetched "$install_args"
|
|
|
|
$ErrorActionPreference = $old_erroractionpreference
|
|
}
|
|
|
|
function Get-TargetTriple() {
|
|
try {
|
|
# NOTE: this might return X64 on ARM64 Windows, which is OK since emulation is available.
|
|
# It works correctly starting in PowerShell Core 7.3 and Windows PowerShell in Win 11 22H2.
|
|
# Ideally this would just be
|
|
# [System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture
|
|
# but that gets a type from the wrong assembly on Windows PowerShell (i.e. not Core)
|
|
$a = [System.Reflection.Assembly]::LoadWithPartialName("System.Runtime.InteropServices.RuntimeInformation")
|
|
$t = $a.GetType("System.Runtime.InteropServices.RuntimeInformation")
|
|
$p = $t.GetProperty("OSArchitecture")
|
|
# Possible OSArchitecture Values: https://learn.microsoft.com/dotnet/api/system.runtime.interopservices.architecture
|
|
# Rust supported platforms: https://doc.rust-lang.org/stable/rustc/platform-support.html
|
|
switch ($p.GetValue($null).ToString())
|
|
{
|
|
"X86" { return "i686-pc-windows-msvc" }
|
|
"X64" { return "x86_64-pc-windows-msvc" }
|
|
"Arm" { return "thumbv7a-pc-windows-msvc" }
|
|
"Arm64" { return "aarch64-pc-windows-msvc" }
|
|
}
|
|
} catch {
|
|
# The above was added in .NET 4.7.1, so Windows PowerShell in versions of Windows
|
|
# prior to Windows 10 v1709 may not have this API.
|
|
Write-Verbose "Get-TargetTriple: Exception when trying to determine OS architecture."
|
|
Write-Verbose $_
|
|
}
|
|
|
|
# This is available in .NET 4.0. We already checked for PS 5, which requires .NET 4.5.
|
|
Write-Verbose("Get-TargetTriple: falling back to Is64BitOperatingSystem.")
|
|
if ([System.Environment]::Is64BitOperatingSystem) {
|
|
return "x86_64-pc-windows-msvc"
|
|
} else {
|
|
return "i686-pc-windows-msvc"
|
|
}
|
|
}
|
|
|
|
function Download($download_url, $platforms) {
|
|
# FIXME: make this something we lookup based on the current machine
|
|
$arch = Get-TargetTriple
|
|
|
|
if (-not $platforms.ContainsKey($arch)) {
|
|
# X64 is well-supported, including in emulation on ARM64
|
|
Write-Verbose "$arch is not availablem falling back to X64"
|
|
$arch = "x86_64-pc-windows-msvc"
|
|
}
|
|
|
|
if (-not $platforms.ContainsKey($arch)) {
|
|
# should not be possible, as currently we always produce X64 binaries.
|
|
$platforms_json = ConvertTo-Json $platforms
|
|
throw "ERROR: could not find binaries for this platform. Last platform tried: $arch platform info: $platforms_json"
|
|
}
|
|
|
|
# Lookup what we expect this platform to look like
|
|
$info = $platforms[$arch]
|
|
$zip_ext = $info["zip_ext"]
|
|
$bin_names = $info["bins"]
|
|
$artifact_name = $info["artifact_name"]
|
|
|
|
# Make a new temp dir to unpack things to
|
|
$tmp = New-Temp-Dir
|
|
$dir_path = "$tmp\$app_name$zip_ext"
|
|
|
|
# Download and unpack!
|
|
$url = "$download_url/$artifact_name"
|
|
"Downloading $app_name $app_version $arch" | Out-Host
|
|
" from $url" | Out-Host
|
|
" to $dir_path" | Out-Host
|
|
$wc = New-Object Net.Webclient
|
|
$wc.downloadFile($url, $dir_path)
|
|
|
|
"Unpacking to $tmp" | Out-Host
|
|
|
|
# Select the tool to unpack the files with.
|
|
#
|
|
# As of windows 10(?), powershell comes with tar preinstalled, but in practice
|
|
# it only seems to support .tar.gz, and not xz/zstd. Still, we should try to
|
|
# forward all tars to it in case the user has a machine that can handle it!
|
|
switch -Wildcard ($zip_ext) {
|
|
".zip" {
|
|
Expand-Archive -Path $dir_path -DestinationPath "$tmp";
|
|
Break
|
|
}
|
|
".tar.*" {
|
|
tar xf $dir_path --strip-components 1 -C "$tmp";
|
|
Break
|
|
}
|
|
Default {
|
|
throw "ERROR: unknown archive format $zip_ext"
|
|
}
|
|
}
|
|
|
|
# Let the next step know what to copy
|
|
$bin_paths = @()
|
|
foreach ($bin_name in $bin_names) {
|
|
" Unpacked $bin_name" | Out-Host
|
|
$bin_paths += "$tmp\$bin_name"
|
|
}
|
|
return $bin_paths
|
|
}
|
|
|
|
function Invoke-Installer($bin_paths) {
|
|
# FIXME: respect $CARGO_HOME if set
|
|
# FIXME: add a flag that lets the user pick this dir
|
|
# FIXME: try to detect other "nice" dirs on the user's PATH?
|
|
# FIXME: detect if the selected install dir exists or is on PATH?
|
|
$dest_dir = New-Item -Force -ItemType Directory -Path (Join-Path $HOME ".cargo\bin")
|
|
|
|
"Installing to $dest_dir" | Out-Host
|
|
# Just copy the binaries from the temp location to the install dir
|
|
foreach ($bin_path in $bin_paths) {
|
|
Copy-Item "$bin_path" -Destination "$dest_dir"
|
|
Remove-Item "$bin_path" -Recurse -Force
|
|
}
|
|
|
|
"Everything's installed!" | Out-Host
|
|
}
|
|
|
|
function Initialize-Environment() {
|
|
If (($PSVersionTable.PSVersion.Major) -lt 5) {
|
|
Write-Error "PowerShell 5 or later is required to install $app_name."
|
|
Write-Error "Upgrade PowerShell: https://docs.microsoft.com/en-us/powershell/scripting/setup/installing-windows-powershell"
|
|
break
|
|
}
|
|
|
|
# show notification to change execution policy:
|
|
$allowedExecutionPolicy = @('Unrestricted', 'RemoteSigned', 'ByPass')
|
|
If ((Get-ExecutionPolicy).ToString() -notin $allowedExecutionPolicy) {
|
|
Write-Error "PowerShell requires an execution policy in [$($allowedExecutionPolicy -join ", ")] to run $app_name."
|
|
Write-Error "For example, to set the execution policy to 'RemoteSigned' please run :"
|
|
Write-Error "'Set-ExecutionPolicy RemoteSigned -scope CurrentUser'"
|
|
break
|
|
}
|
|
|
|
# GitHub requires TLS 1.2
|
|
If ([System.Enum]::GetNames([System.Net.SecurityProtocolType]) -notcontains 'Tls12') {
|
|
Write-Error "Installing $app_name requires at least .NET Framework 4.5"
|
|
Write-Error "Please download and install it first:"
|
|
Write-Error "https://www.microsoft.com/net/download"
|
|
break
|
|
}
|
|
}
|
|
|
|
function New-Temp-Dir() {
|
|
[CmdletBinding(SupportsShouldProcess)]
|
|
param()
|
|
$parent = [System.IO.Path]::GetTempPath()
|
|
[string] $name = [System.Guid]::NewGuid()
|
|
New-Item -ItemType Directory -Path (Join-Path $parent $name)
|
|
}
|
|
|
|
Install-Binary "$Args"
|