# Installs lsh, the LogiShell command line, for this user on Windows: # irm https://cli.lsh.dev/install.ps1 | iex # # $env:LSH_VERSION a release to install (0.2.0); default: the latest # $env:LSH_INSTALL_DIR where lsh.exe goes; default: %LOCALAPPDATA%\Programs\lsh # $env:LSH_DL where releases live; default: https://cli.lsh.dev/cli # # No administrator rights, PATH is not changed silently: the script prints the command that # adds the directory. Layout of the release server: harness/cli/dist/README.md. & { Set-StrictMode -Version 3.0 $ErrorActionPreference = 'Stop' $ProgressPreference = 'SilentlyContinue' function Fail([string]$Message, [string]$Hint) { Write-Host "error: $Message" -ForegroundColor Red if ($Hint) { Write-Host " hint: $Hint" -ForegroundColor DarkGray } throw "lsh install: $Message" } # TLS 1.2 for Windows PowerShell 5.1 (PowerShell 7 already has it). try { [Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12 } catch { } $base = if ($env:LSH_DL) { $env:LSH_DL.TrimEnd('/') } else { 'https://cli.lsh.dev/cli' } $dir = if ($env:LSH_INSTALL_DIR) { $env:LSH_INSTALL_DIR } else { Join-Path $env:LOCALAPPDATA 'Programs\lsh' } $version = if ($env:LSH_VERSION) { $env:LSH_VERSION.TrimStart('v') } else { '' } # The architecture of the OS, not of this process (a 32 bit or emulated shell lies). $arch = $env:PROCESSOR_ARCHITEW6432 if (-not $arch) { $arch = $env:PROCESSOR_ARCHITECTURE } switch ($arch) { 'AMD64' { $target = 'x86_64-pc-windows-msvc' } 'ARM64' { # No native ARM64 build yet: the x64 build runs under the emulation of Windows 11. $target = 'x86_64-pc-windows-msvc' Write-Host '! no native ARM64 build yet, installing the x64 build (runs under emulation)' -ForegroundColor Yellow } default { Fail "no lsh build for Windows on $arch" 'builds: https://lsh.dev/dl' } } $name = "lsh-$target.exe" if ($version) { $url = "$base/v$version/$name" try { $sumText = [string](Invoke-RestMethod -UseBasicParsing -Uri "$base/v$version/lsh-$target.sha256") } catch { Fail "no lsh $version for $target at $base/v$version/" 'see the releases at https://lsh.dev/dl' } $sum = ($sumText.Trim() -split '\s+')[0].ToLowerInvariant() } else { try { $manifest = Invoke-RestMethod -UseBasicParsing -Uri "$base/latest.json" } catch { Fail "could not read $base/latest.json: $($_.Exception.Message)" 'check the network, or set $env:LSH_DL to a mirror' } $version = ([string]$manifest.version).TrimStart('v') if (-not $version) { Fail "$base/latest.json names no version" 'report it at https://lsh.dev/gh' } $asset = $manifest.assets.PSObject.Properties[$target] if (-not $asset) { Fail "lsh $version has no build for $target" 'see the builds at https://lsh.dev/dl' } $url = [string]$asset.Value.url $sum = ([string]$asset.Value.sha256).ToLowerInvariant() } if ($sum -notmatch '^[0-9a-f]{64}$') { Fail "no valid sha256 for $name" 'report it at https://lsh.dev/gh' } Write-Host "installing lsh $version for $target" try { New-Item -ItemType Directory -Force -Path $dir | Out-Null } catch { Fail "cannot create $dir" 'pick another directory: $env:LSH_INSTALL_DIR = "