Skip to content

Commit ca32ab3

Browse files
authored
Merge pull request #5906 from kit-ty-kate/windows-installer
Provide an install.ps1 PowerShell script to install opam on Windows
2 parents bd8e7db + b1888a4 commit ca32ab3

File tree

2 files changed

+121
-0
lines changed

2 files changed

+121
-0
lines changed

master_changes.md

+1
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ users)
7373
## Release scripts
7474

7575
## Install script
76+
* Provide a shell/install.ps1 PowerShell script to install opam on Windows [#5906 @kit-ty-kate @dra27]
7677

7778
## Admin
7879

shell/install.ps1

+120
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
<#
2+
.SYNOPSIS
3+
Downloads and installs opam from binaries distributed on GitHub.
4+
5+
.DESCRIPTION
6+
Script is able to perform either a per-machine or per-user installation of
7+
opam for any version of opam after 2.2.0~beta2. By default it will install the
8+
latest released version.
9+
10+
.LINK
11+
See https://opam.ocaml.org/doc/Install.html for further information.
12+
#>
13+
14+
param (
15+
# Install the latest alpha, beta or rc
16+
[switch]$Dev,
17+
# Install this specific version of opam instead of the latest
18+
[string]$Version = "2.2.0~rc1",
19+
# Specify the installation directory for the opam binary
20+
[string]$OpamBinDir = $null
21+
)
22+
23+
$DevVersion = "2.2.0~rc1"
24+
$IsAdmin = (New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
25+
$DefaultBinDir = If ($IsAdmin) {"$Env:ProgramFiles\opam\bin"} Else {"$Env:LOCALAPPDATA\Programs\opam\bin"}
26+
27+
$SHA512s = @{
28+
"opam-2.2.0-beta2-x86_64-windows.exe" = "74f034ccc30ef0b2041283ff125be2eab565d4019e79f946b515046c4c290a698266003445f38b91321a9ef931093651f861360906ff06c076c24d18657e2aaf";
29+
"opam-2.2.0-beta3-x86_64-windows.exe" = "f09337d94e06cedb379c5bf45a50a79cf2b2e529d7c2bb9b35c8a56d40902ff8c7e3f4de9c75fb5c8dd8272b87b2a2645b14e40ef965376ef0d19afd923acf3b";
30+
"opam-2.2.0-rc1-x86_64-windows.exe" = "f2ec830a5706c45cb56a96713e296ef756c3f2904ca15f7c2ad0442916a9585fa1de8070208f2a6bb3a84dc74b677f946f5bc386c8ed1489da802b1d66a5e094";
31+
}
32+
33+
Function DownloadAndCheck {
34+
param (
35+
[string]$OpamBinUrl,
36+
[string]$OpamBinTmpLoc,
37+
[string]$OpamBinName
38+
)
39+
40+
if (-not $SHA512s.ContainsKey($OpamBinName)) {
41+
throw "no sha"
42+
}
43+
44+
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
45+
(New-Object System.Net.WebClient).DownloadFile($OpamBinUrl, $OpamBinTmpLoc)
46+
$Hash = (Get-FileHash -Path $OpamBinTmpLoc -Algorithm SHA512).Hash
47+
48+
if ($Hash -ne "$($SHA512s[$OpamBinName])") {
49+
throw "Checksum mismatch, a problem occurred during download."
50+
}
51+
}
52+
53+
if (-not [System.Environment]::Is64BitOperatingSystem) {
54+
throw "opam requires a 64-bit version of Windows"
55+
}
56+
57+
if ($Dev.IsPresent) {
58+
$Version = $DevVersion
59+
}
60+
61+
$Tag = $Version.Replace("~", "-")
62+
$Arch = "x86_64"
63+
$OS = "windows"
64+
$OpamBinUrlBase = "https://github.com/ocaml/opam/releases/download/"
65+
$OpamBinName = "opam-$Tag-$Arch-$OS.exe"
66+
$OpamBinUrl = "$OpamBinUrlBase$Tag/$OpamBinName"
67+
68+
$OpamBinTmpLoc = "$Env:TEMP\$OpamBinName"
69+
70+
if (-not (Test-Path -Path $OpamBinTmpLoc -IsValid)) {
71+
throw "Failed to determine a temporary path for downloading opam"
72+
}
73+
74+
Write-Host "## Downloading opam $Version for Windows on x86_64"
75+
$esc = [char]27
76+
77+
if ([string]::IsNullOrEmpty($OpamBinDir)) {
78+
$OpamBinDir = Read-Host "## Where should it be installed? [$esc[1m$DefaultBinDir$esc[0m]"
79+
if ([string]::IsNullOrEmpty($OpamBinDir)) {
80+
$OpamBinDir = $DefaultBinDir
81+
}
82+
}
83+
84+
if (-not (Test-Path -Path $OpamBinDir -IsValid) -or $OpamBinDir -contains ';') {
85+
throw "Destination given for installation is not a valid path"
86+
}
87+
88+
# Check existing opam binaries
89+
$AllOpam = Get-Command -All -Name opam -CommandType Application -ErrorAction Ignore | ForEach-Object -MemberName Source
90+
foreach($OneOpam in $AllOpam) {
91+
if ($OneOpam -ne "$OpamBinDir\opam.exe") {
92+
throw "We detected another opam binary installed at '$OneOpam'. To ensure problems won't occur later, please uninstall it or remove it from the PATH"
93+
}
94+
}
95+
96+
DownloadAndCheck -OpamBinUrl $OpamBinUrl -OpamBinTmpLoc $OpamBinTmpLoc -OpamBinName $OpamBinName
97+
98+
# Install the binary
99+
if (-not (Test-Path -Path $OpamBinDir -PathType Container)) {
100+
[void](New-Item -Force -Path $OpamBinDir -Type Directory)
101+
}
102+
[void](Move-Item -Force -Path $OpamBinTmpLoc -Destination "$OpamBinDir\opam.exe")
103+
104+
# Add the newly installed binary to PATH for this and future sessions
105+
$EnvTarget = If ($IsAdmin) {'MACHINE'} Else {'USER'}
106+
foreach ($loc in $EnvTarget, 'PROCESS') {
107+
$PATH = [Environment]::GetEnvironmentVariable('PATH', $loc)
108+
if (-not ($PATH -split ';' -contains $OpamBinDir)) {
109+
[Environment]::SetEnvironmentVariable('PATH', "$OpamBinDir;$PATH", $loc)
110+
if ($loc -ne 'PROCESS') {
111+
Write-Host "## opam has added $OpamBinDir to the $loc PATH for future sessions"
112+
Write-Host ""
113+
Write-Host "Please use the Environment Variables editor in Control Panel to remove"
114+
Write-Host "this entry if you subsequently decide to remove opam from your system"
115+
Write-Host "(it can be started by running $esc[1mrundll32 sysdm.cpl,EditEnvironmentVariables$esc[0m)"
116+
}
117+
}
118+
}
119+
120+
Write-Host "## opam $Version installed to $OpamBinDir"

0 commit comments

Comments
 (0)