<# .SYNOPSIS Script to bootstrap a Haskell environment .DESCRIPTION This is the windows GHCup installer, installing: * ghcup - The Haskell toolchain installer" * ghc - The Glasgow Haskell Compiler" * msys2 - Unix-style toolchain needed for dependencies and tools * cabal - The Cabal build tool for managing Haskell software" * stack - (optional) A cross-platform program for developing Haskell projects" * hls - (optional) A language server for developers to integrate with their editor/IDE" By default, the installation is non-interactive, unless you run it with 'Interactive $true'. #> param ( # Run an interactive installation [switch]$Interactive, # Do minimal installation of ghcup and msys2 only [switch]$Minimal, # Run the final bootstrap script via 'bash' instead of a full newly spawned msys2 shell [switch]$InBash, # Overwrite (or rather backup) a previous install [switch]$Overwrite, # Skip adjusting cabal.config with mingw paths [switch]$NoAdjustCabalConfig, # Whether to install stack as well [switch]$InstallStack, # Whether to install hls as well [switch]$InstallHLS, # Specify the install root (default: 'C:\') [string]$InstallDir, # Specify the bootstrap url (default: 'https://www.haskell.org/ghcup/sh/bootstrap-haskell') [string]$BootstrapUrl, # Instead of installing a new MSys2, use an existing installation [string]$ExistingMsys2Dir, # Specify the cabal root directory (default: '$InstallDir\cabal') [string]$CabalDir, # Whether to disable use of curl.exe [switch]$DisableCurl, # The Msys2 version to download (e.g. 20221216) [string]$Msys2Version, # The Msys2 sha256sum hash [string]$Msys2Hash ) $DefaultMsys2Version = "20221216" $DefaultMsys2Hash = "18370d32b0264915c97e3d7c618f7b32d48ad80858923883fde5145acd32ca0f" $Silent = !$Interactive function Print-Msg { param ( [Parameter(Mandatory=$true, HelpMessage='String to output')][string]$msg, [string]$color = "Green" ) Write-Host ('{0}' -f $msg) -ForegroundColor $color } function Create-Shortcut { param ( [Parameter(Mandatory=$true,HelpMessage='Target path')][string]$SourceExe , [Parameter(Mandatory=$true,HelpMessage='Arguments to the path/exe')][AllowEmptyString()]$ArgumentsToSourceExe , [Parameter(Mandatory=$true,HelpMessage='The destination of the desktop link')][string]$DestinationPath , [Parameter(Mandatory=$true,HelpMessage='Temporary path to create the link at')][string]$TempPath ) # we save to a temp dir first due to # https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/267 $DesktopDir = [Environment]::GetFolderPath("Desktop") if (!(Test-Path -Path ('{0}' -f $TempPath))) { New-Item -Path $TempPath -ItemType "directory" } $TmpFile = ('{0}\{1}' -f $TempPath, $DestinationPath) $FinalDest = ('{0}\{1}' -f $DesktopDir, $DestinationPath) $WshShell = New-Object -comObject WScript.Shell $Shortcut = $WshShell.CreateShortcut($TmpFile) $Shortcut.TargetPath = $SourceExe if($ArgumentsToSourceExe) { $Shortcut.Arguments = $ArgumentsToSourceExe } $Shortcut.Save() if ((Test-Path -Path ('{0}' -f $FinalDest))) { Remove-Item -LiteralPath $FinalDest -Force } Move-Item -LiteralPath $TmpFile -Destination $FinalDest } function Add-EnvPath { param( [Parameter(Mandatory=$true,HelpMessage='The Path to add to Users environment')] [string] $Path, [ValidateSet('Machine', 'User', 'Session')] [string] $Container = 'Session' ) if ($Container -eq 'Session') { $envPaths = [Collections.Generic.List[String]]($env:Path -split ([IO.Path]::PathSeparator)) if ($envPaths -notcontains $Path) { $envPaths.Add($Path) $env:PATH = $envPaths -join ([IO.Path]::PathSeparator) } } else { [Microsoft.Win32.RegistryHive]$hive, $keyPath = switch ($Container) { 'Machine' { 'LocalMachine', 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment' } 'User' { 'CurrentUser', 'Environment' } } $hiveKey = $envKey = $null try { $hiveKey = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey($hive, '') $envKey = $hiveKey.OpenSubKey($keyPath, $true) $rawPath = $envKey.GetValue('PATH', '', 'DoNotExpandEnvironmentNames') $envPaths = [Collections.Generic.List[String]]($rawPath -split ([IO.Path]::PathSeparator)) if ($envPaths -notcontains $Path) { $envPaths.Add($Path) $envKey.SetValue('PATH', ($envPaths -join ([IO.Path]::PathSeparator)), 'ExpandString') } } finally { if ($envKey) { $envKey.Close() } if ($hiveKey) { $hiveKey.Close() } } } } filter Get-FileSize { '{0:N2} {1}' -f $( if ($_ -lt 1kb) { $_, 'Bytes' } elseif ($_ -lt 1mb) { ($_/1kb), 'KB' } elseif ($_ -lt 1gb) { ($_/1mb), 'MB' } elseif ($_ -lt 1tb) { ($_/1gb), 'GB' } elseif ($_ -lt 1pb) { ($_/1tb), 'TB' } else { ($_/1pb), 'PB' } ) } function Get-FileWCSynchronous{ param( [Parameter(Mandatory=$true)] [string]$url, [string]$destinationFolder="$env:USERPROFILE\Downloads", [switch]$includeStats ) $wc = New-Object -TypeName Net.WebClient $wc.UseDefaultCredentials = $true $destination = Join-Path -Path $destinationFolder -ChildPath ($url | Split-Path -Leaf) $start = Get-Date $wc.DownloadFile($url, $destination) $elapsed = ((Get-Date) - $start).ToString('hh\:mm\:ss') $totalSize = (Get-Item -Path $destination).Length | Get-FileSize if ($includeStats.IsPresent){ [PSCustomObject]@{Name=$MyInvocation.MyCommand;TotalSize=$totalSize;Time=$elapsed} } Get-Item -Path $destination | Unblock-File } function Test-AbsolutePath { Param ( [Parameter(Mandatory=$True)] [ValidateScript({[System.IO.Path]::IsPathRooted($_)})] [String]$Path ) } function Exec { [CmdletBinding()] param( [Parameter(Position = 0, Mandatory = 1)][string]$cmd, [Parameter()][string]$errorMessage, [parameter(ValueFromRemainingArguments = $true)] [string[]]$Passthrough ) & $cmd @Passthrough if ($lastexitcode -ne 0) { if (!($errorMessage)) { throw ('Exec: Error executing command {0} with arguments ''{1}''' -f $cmd, "$Passthrough") } else { throw ('Exec: ' + $errorMessage) } } } $ErrorActionPreference = 'Stop' $GhcupBasePrefixEnv = [System.Environment]::GetEnvironmentVariable('GHCUP_INSTALL_BASE_PREFIX', 'user') if (Get-Command -Name 'chocolatey.exe' -ErrorAction SilentlyContinue) { if (!($Silent)) { Print-Msg -color Magenta -msg (@' Chocolatey was detected on your system. It is capable of installing the Haskell toolchain as well. If you want to rather use that instead of ghcup, abort the installation and run the following at an elevated command prompt: choco install haskell-dev refreshenv '@) $decision = $Host.UI.PromptForChoice('' , 'Continue with GHCup installation?' , [System.Management.Automation.Host.ChoiceDescription[]] @('&Continue' '&Abort'), 0) if ($decision -eq 1) { Exit 0 } } } if ($GhcupBasePrefixEnv) { $defaultGhcupBasePrefix = $GhcupBasePrefixEnv } elseif (!($InstallDir)) { $partitions = Get-CimInstance win32_logicaldisk $defaultGhcupBasePrefix = $null foreach ($p in $partitions){ try { if ($p."FreeSpace" -lt 5368709120) { # at least 5 GB are needed throw ("Not enough free space on {0}" -f $p."DeviceId") } $null = New-Item -Path ('{0}\' -f $p."DeviceId") -Name "ghcup.test" -ItemType "directory" -Force $defaultGhcupBasePrefix = ('{0}\' -f $p."DeviceId") Remove-Item -LiteralPath ('{0}\ghcup.test' -f $p."DeviceId") break } catch { Print-Msg -color Yellow -msg ("{0} not writable or not enough disk space, trying next device" -f $p."DeviceId") } } if ($defaultGhcupBasePrefix) { Print-Msg -color Green -msg ("Picked {0} as default Install prefix!" -f $defaultGhcupBasePrefix) } else { Print-Msg -color Red -msg "Couldn't find a writable partition with at least 5GB free disk space!" Exit 1 } } # ask for base install prefix if ($Silent -and !($InstallDir)) { $GhcupBasePrefix = $defaultGhcupBasePrefix } elseif ($InstallDir) { if (!(Test-Path -LiteralPath ('{0}' -f $InstallDir) -IsValid)) { Print-Msg -color Red -msg "Not a valid directory! (InstallDir)" Exit 1 } elseif (!(Split-Path -IsAbsolute -Path "$InstallDir")) { Print-Msg -color Red -msg "Non-absolute Path specified! (InstallDir)" Exit 1 } else { $GhcupBasePrefix = $InstallDir } } else { while ($true) { Print-Msg -color Magenta -msg (@' Welcome to Haskell! This script can download and install the following programs: * ghcup - The Haskell toolchain installer * ghc - The Glasgow Haskell Compiler * msys2 - A linux-style toolchain environment required for many operations * cabal - The Cabal build tool for managing Haskell software * stack - (optional) A cross-platform program for developing Haskell projects * hls - (optional) A language server for developers to integrate with their editor/IDE Please note that ANTIVIRUS may interfere with the installation. If you experience problems, consider disabling it temporarily. Where to install to (this should be a short Path, preferably a Drive like 'C:\')? If you accept this path, binaries will be installed into '{0}ghcup\bin' and msys2 into '{0}ghcup\msys64'. Press enter to accept the default [{0}]: '@ -f $defaultGhcupBasePrefix) $basePrefixPrompt = Read-Host $GhcupBasePrefix = ($defaultGhcupBasePrefix,$basePrefixPrompt)[[bool]$basePrefixPrompt] if (!($GhcupBasePrefix.EndsWith('\'))) { $GhcupBasePrefix = ('{0}\' -f $GhcupBasePrefix) } $GhcupBasePrefix = $GhcupBasePrefix.TrimEnd().TrimStart() if (!($GhcupBasePrefix)) { Print-Msg -color Red -msg "No directory specified!" } elseif (!(Test-Path -LiteralPath ('{0}' -f $GhcupBasePrefix))) { Print-Msg -color Red -msg "Directory does not exist, need to specify an existing Drive/Directory" } elseif (!(Split-Path -IsAbsolute -Path "$GhcupBasePrefix")) { Print-Msg -color Red -msg "Invalid/Non-absolute Path specified" } else { Break } } } Print-Msg -msg ('Setting env variable GHCUP_INSTALL_BASE_PREFIX to ''{0}''' -f $GhcupBasePrefix) $null = [Environment]::SetEnvironmentVariable("GHCUP_INSTALL_BASE_PREFIX", $GhcupBasePrefix, [System.EnvironmentVariableTarget]::User) $GhcupDir = ('{0}\ghcup' -f $GhcupBasePrefix) if ($ExistingMsys2Dir) { if (!(Test-Path -LiteralPath ('{0}' -f $ExistingMsys2Dir) -IsValid)) { Print-Msg -color Red -msg "Not a valid directory! (ExistingMsys2Dir)" Exit 1 } elseif (!(Split-Path -IsAbsolute -Path "$ExistingMsys2Dir")) { Print-Msg -color Red -msg "Non-absolute Path specified! (ExistingMsys2Dir)" Exit 1 } else { $MsysDir = $ExistingMsys2Dir } } else { $MsysDir = ('{0}\msys64' -f $GhcupDir) } $Bash = ('{0}\usr\bin\bash' -f $MsysDir) if (!($BootstrapUrl)) { $BootstrapUrl = 'https://www.haskell.org/ghcup/sh/bootstrap-haskell' } $GhcupMsys2 = [System.Environment]::GetEnvironmentVariable('GHCUP_MSYS2', 'user') Print-Msg -msg 'Preparing for GHCup installation...' # ask what to do in case ghcup is already installed if (Test-Path -LiteralPath ('{0}' -f $GhcupDir)) { Print-Msg -msg ('GHCup already installed at ''{0}''...' -f $GhcupDir) if ($Overwrite) { $decision = 0 } elseif (!($Silent)) { $decision = $Host.UI.PromptForChoice('Install GHCup' , 'GHCup is already installed, what do you want to do?' , [System.Management.Automation.Host.ChoiceDescription[]] @('&Reinstall' '&Continue' '&Abort'), 1) } else { $decision = 1 } if ($decision -eq 0) { $suffix = [IO.Path]::GetRandomFileName() Print-Msg -msg ('Backing up {0} to {0}-{1} ...' -f $GhcupDir, $suffix) Rename-Item -Path ('{0}' -f $GhcupDir) -NewName ('{0}-{1}' -f $GhcupDir, $suffix) } elseif ($decision -eq 1) { Print-Msg -msg 'Continuing installation...' } elseif ($decision -eq 2) { Exit 0 } } $null = New-Item -Path ('{0}' -f $GhcupDir) -ItemType 'directory' -ErrorAction SilentlyContinue $null = New-Item -Path ('{0}' -f $GhcupDir) -Name 'bin' -ItemType 'directory' -ErrorAction SilentlyContinue # ask for cabal dir destination if ($CabalDir) { $CabDirEnv = $CabalDir if (!($CabDirEnv)) { Print-Msg -color Red -msg "No directory specified!" Exit 1 } elseif (!(Split-Path -IsAbsolute -Path "$CabDirEnv")) { Print-Msg -color Red -msg "Invalid/Non-absolute Path specified" Exit 1 } } elseif (!($Silent)) { while ($true) { $defaultCabalDir = ('{0}\cabal' -f $GhcupBasePrefix) Print-Msg -color Magenta -msg ('Specify Cabal directory (this is where haskell packages end up){1}Press enter to accept the default [{0}]:' -f $defaultCabalDir, "`n") $CabalDirPrompt = Read-Host $CabDirEnv = ($defaultCabalDir,$CabalDirPrompt)[[bool]$CabalDirPrompt] $CabDirEnv = $CabDirEnv.TrimEnd().TrimStart() if (!($CabDirEnv)) { Print-Msg -color Red -msg "No directory specified!" } elseif (!(Split-Path -IsAbsolute -Path "$CabDirEnv")) { Print-Msg -color Red -msg "Invalid/Non-absolute Path specified" } else { Break } } } else { $CabDirEnv = ('{0}\cabal' -f $GhcupBasePrefix) } # ask whether to install HLS if (!($InstallHLS)) { if (!($Silent)) { $HLSdecision = $Host.UI.PromptForChoice('Install HLS' , 'Do you want to install the haskell-language-server (HLS) for development purposes as well?' , [System.Management.Automation.Host.ChoiceDescription[]] @('&Yes' '&No' '&Abort'), 1) if ($HLSdecision -eq 0) { $InstallHLS = $true } elseif ($HLSdecision -eq 2) { Exit 0 } } } # ask whether to install stack if (!($InstallStack)) { if (!($Silent)) { $StackDecision = $Host.UI.PromptForChoice('Install stack' , 'Do you want to install stack as well?' , [System.Management.Automation.Host.ChoiceDescription[]] @('&Yes' '&No' '&Abort'), 1) if ($StackDecision -eq 0) { $InstallStack = $true } elseif ($StackDecision -eq 2) { Exit 0 } } } # mingw foo Print-Msg -msg 'First checking for Msys2...' if (!(Test-Path -Path ('{0}' -f $MsysDir))) { if ($Silent) { $msys2Decision = 0 } else { $msys2Decision = $Host.UI.PromptForChoice('Install MSys2' , 'Do you want GHCup to install a default MSys2 toolchain (recommended)?' , [System.Management.Automation.Host.ChoiceDescription[]] @('&Yes' '&No'), 0) } if ($msys2Decision -eq 0) { Print-Msg -msg ('...Msys2 doesn''t exist, installing into {0}' -f $MsysDir) Print-Msg -msg 'Starting installation in 5 seconds, this may take a while...' Start-Sleep -s 5 # Download the archive if (!($Msys2Version)) { $Msys2Version = $DefaultMsys2Version } if (!($Msys2Hash)) { $Msys2Hash = $DefaultMsys2Hash } Print-Msg -msg ('Downloading Msys2 archive {0}...' -f $Msys2Version) $archive = ('msys2-base-x86_64-{0}.sfx.exe' -f $Msys2Version) $msysUrl = ('https://downloads.haskell.org/ghcup/msys2/{0}' -f "$archive") $archivePath = ('{0}\{1}' -f ([IO.Path]::GetTempPath()), "$archive") if ((Get-Command -Name 'curl.exe' -ErrorAction SilentlyContinue) -and !($DisableCurl)) { Exec "curl.exe" '-o' "$archivePath" "$msysUrl" } else { Get-FileWCSynchronous -url "$msysUrl" -destinationFolder ([IO.Path]::GetTempPath()) -includeStats } $Msys2HashChecked = Get-FileHash -Algorithm SHA256 "${archivePath}" if (!($Msys2HashChecked.Hash -eq $Msys2Hash)) { Print-Msg -color Red -msg ("Hashes don't match, got {0}, but expected {1}" -f $Msys2HashChecked, $Msys2Hash) Exit 1 } Print-Msg -msg 'Extracting Msys2 archive...' $null = & "$archivePath" '-y' ('-o{0}' -f $GhcupDir) # Extract Remove-Item -Path "$archivePath" Print-Msg -msg 'Processing MSYS2 bash for first time use...' Exec "$Bash" '-lc' 'exit' Exec "$env:windir\system32\taskkill.exe" /F /FI `"MODULES eq msys-2.0.dll`" Print-Msg -msg 'Upgrading full system...' Exec "$Bash" '-lc' 'pacman --noconfirm -Syuu' Print-Msg -msg 'Upgrading full system twice...' Exec "$Bash" '-lc' 'pacman --noconfirm -Syuu' Print-Msg -msg 'Installing Dependencies...' Exec "$Bash" '-lc' 'pacman --noconfirm -S --needed curl autoconf mingw-w64-x86_64-pkgconf' Print-Msg -msg 'Updating SSL root certificate authorities...' Exec "$Bash" '-lc' 'pacman --noconfirm -S ca-certificates' Print-Msg -msg 'Setting default home directory...' Exec "$Bash" '-lc' "sed -i -e 's/db_home:.*$/db_home: windows/' /etc/nsswitch.conf" } elseif ($msys2Decision -eq 1) { Print-Msg -color Yellow -msg 'Skipping MSys2 installation.' while ($true) { if ($GhcupMsys2) { $defaultMsys2Dir = $GhcupMsys2 Print-Msg -color Magenta -msg ('Input existing MSys2 toolchain directory.{1}Press enter to accept the default [{0}]:' -f $defaultMsys2Dir, "`n") $MsysDirPrompt = Read-Host $MsysDir = ($defaultMsys2Dir,$MsysDirPrompt)[[bool]$MsysDirPrompt] } else { Print-Msg -color Magenta -msg 'Input existing MSys2 toolchain directory:' $MsysDir = Read-Host } $MsysDir = $MsysDir.TrimEnd().TrimStart() if (!($MsysDir)) { Print-Msg -color Red -msg "No directory specified!" } elseif (!(Test-Path -LiteralPath ('{0}' -f $MsysDir))) { Print-Msg -color Red -msg ('MSys2 installation at ''{0}'' could not be found!' -f $MsysDir) } elseif (!(Split-Path -IsAbsolute -Path "$MsysDir")) { Print-Msg -color Red -msg "Invalid/Non-absolute Path specified" } else { Break } } Print-Msg -msg ('Setting GHCUP_MSYS2 env var to ''{0}''' -f $MsysDir) $null = [Environment]::SetEnvironmentVariable("GHCUP_MSYS2", $MsysDir, [System.EnvironmentVariableTarget]::User) $Bash = ('{0}\usr\bin\bash' -f $MsysDir) } } else { Print-Msg -msg ('...Msys2 found in {0} ...skipping Msys2 installation.' -f $MsysDir) Print-Msg -msg 'Starting installation in 5 seconds, this may take a while...' Start-Sleep -s 5 } Print-Msg -msg 'Creating shortcuts...' $uninstallShortCut = @' $decision = $Host.UI.PromptForChoice('Uninstall Haskell' , 'Do you want to uninstall all of the haskell toolchain, including GHC, Cabal, Stack and GHCup itself?' , [System.Management.Automation.Host.ChoiceDescription[]] @('&Uninstall' '&Abort'), 0) if ($decision -eq 1) { Exit 0 } Write-Host 'Removing ghcup toolchain' -ForegroundColor Green ghcup nuke Write-Host 'Unsetting GHCUP_INSTALL_BASE_PREFIX' -ForegroundColor Green [Environment]::SetEnvironmentVariable('GHCUP_INSTALL_BASE_PREFIX', $null, [System.EnvironmentVariableTarget]::User) $ghcupMsys2 = [System.Environment]::GetEnvironmentVariable('GHCUP_MSYS2', 'user') $GhcupBasePrefixEnv = [System.Environment]::GetEnvironmentVariable('GHCUP_INSTALL_BASE_PREFIX', 'user') if ($ghcupMsys2) { $msys2Dir = [IO.Path]::GetFullPath($ghcupMsys2) $baseDir = [IO.Path]::GetFullPath('{0}\ghcup' -f $GhcupBasePrefixEnv) if ($msys2Dir.StartsWith($baseDir)) { Write-Host 'Unsetting GHCUP_MSYS2' -ForegroundColor Green [Environment]::SetEnvironmentVariable('GHCUP_MSYS2', $null, [System.EnvironmentVariableTarget]::User) } else { Write-Host ('GHCUP_MSYS2 env variable is set to a non-standard location {0}. Environment variable not unset. Uninstall manually.' -f $msys2Dir) -ForegroundColor Magenta } } else { Write-Host 'Unsetting GHCUP_MSYS2' -ForegroundColor Green [Environment]::SetEnvironmentVariable('GHCUP_MSYS2', $null, [System.EnvironmentVariableTarget]::User) } Write-Host 'Removing ghcup from PATH env var' -ForegroundColor Green $path = [System.Environment]::GetEnvironmentVariable( 'PATH', 'user' ) $path = ($path.Split(';') | Where-Object { $_ -ne ('{0}\bin' -f $baseDir) }) -join ';' [System.Environment]::SetEnvironmentVariable( 'PATH', $path, 'user' ) Write-Host 'Removing desktop files' -ForegroundColor Green $DesktopDir = [Environment]::GetFolderPath("Desktop") Remove-Item -LiteralPath ('{0}\Install GHC dev dependencies.lnk' -f $DesktopDir) -Force Remove-Item -LiteralPath ('{0}\Mingw haskell shell.lnk' -f $DesktopDir) -Force Remove-Item -LiteralPath ('{0}\Mingw package management docs.url' -f $DesktopDir) -Force Write-Host ('CABAL_DIR env variable is still set to {0} and will be used by cabal regardless of ghcup. You may want to uninstall this manually.' -f [System.Environment]::GetEnvironmentVariable('CABAL_DIR', 'user')) -ForegroundColor Magenta Write-Host 'You may remove this script now.' -ForegroundColor Magenta if ($Host.Name -eq "ConsoleHost") { Write-Host "Press any key to continue..." $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyUp") > $null } '@ $GhcInstArgs = '-mingw64 -mintty -c "pacman --noconfirm -S --needed base-devel gettext autoconf make libtool automake python p7zip patch unzip"' Create-Shortcut -SourceExe ('{0}\msys2_shell.cmd' -f $MsysDir) -ArgumentsToSourceExe $GhcInstArgs -DestinationPath 'Install GHC dev dependencies.lnk' -TempPath $GhcupDir Create-Shortcut -SourceExe ('{0}\msys2_shell.cmd' -f $MsysDir) -ArgumentsToSourceExe '-mingw64' -DestinationPath 'Mingw haskell shell.lnk' -TempPath $GhcupDir Create-Shortcut -SourceExe 'https://www.msys2.org/docs/package-management' -ArgumentsToSourceExe '' -DestinationPath 'Mingw package management docs.url' -TempPath $GhcupDir $DesktopDir = [Environment]::GetFolderPath("Desktop") $null = New-Item -Path $DesktopDir -Name "Uninstall Haskell.ps1" -ItemType "file" -Force -Value $uninstallShortCut Print-Msg -msg ('Adding {0}\bin to Users Path...' -f $GhcupDir) Add-EnvPath -Path ('{0}\bin' -f ([System.IO.Path]::GetFullPath("$GhcupDir"))) -Container 'User' $CabalDirFull = [System.IO.Path]::GetFullPath("$CabDirEnv") Print-Msg -msg ('Setting CABAL_DIR to ''{0}''' -f $CabalDirFull) $null = [Environment]::SetEnvironmentVariable("CABAL_DIR", $CabalDirFull, [System.EnvironmentVariableTarget]::User) Print-Msg -msg 'Starting GHCup installer...' $Msys2Shell = ('{0}\msys2_shell.cmd' -f $MsysDir) # The bootstrap script is always silent, since we ask relevant questions here $SilentExport = 'export BOOTSTRAP_HASKELL_NONINTERACTIVE=1 ;' if (!($InstallStack)) { $StackInstallExport = 'export BOOTSTRAP_HASKELL_INSTALL_NO_STACK=1 ;' } if ($InstallHLS) { $HLSInstallExport = 'export BOOTSTRAP_HASKELL_INSTALL_HLS=1 ;' } if (!($NoAdjustCabalConfig)) { $AdjustCabalConfigExport = 'export BOOTSTRAP_HASKELL_ADJUST_CABAL_CONFIG=1 ;' } if ($Minimal) { $MinimalExport = 'export BOOTSTRAP_HASKELL_MINIMAL=1 ;' } if ($DisableCurl) { $BootstrapDownloader = 'export BOOTSTRAP_HASKELL_DOWNLOADER=wget ;' $DownloadScript = 'wget -O /dev/stdout' } else { $DownloadScript = 'curl --proto ''=https'' --tlsv1.2 -sSf' } if ((Get-Process -ID $PID).ProcessName.StartsWith("bootstrap-haskell") -Or $InBash) { Exec "$Bash" '-lc' ('{4} {6} {7} {8} {9} {10} [ -n ''{1}'' ] && export GHCUP_MSYS2=$(cygpath -m ''{1}'') ; [ -n ''{2}'' ] && export GHCUP_INSTALL_BASE_PREFIX=$(cygpath -m ''{2}/'') ; export PATH=$(cygpath -u ''{3}/bin''):$PATH ; export CABAL_DIR=''{5}'' ; [[ ''{0}'' = https* ]] && {11} {0} | bash || cat $(cygpath -m ''{0}'') | bash' -f $BootstrapUrl, $MsysDir, $GhcupBasePrefix, $GhcupDir, $SilentExport, $CabalDirFull, $StackInstallExport, $HLSInstallExport, $AdjustCabalConfigExport, $MinimalExport, $BootstrapDownloader, $DownloadScript) } else { Exec "$Msys2Shell" '-mingw64' '-mintty' '-shell' 'bash' '-c' ('{4} {6} {7} {8} {9} {10} [ -n ''{1}'' ] && export GHCUP_MSYS2=$(cygpath -m ''{1}'') ; [ -n ''{2}'' ] && export GHCUP_INSTALL_BASE_PREFIX=$(cygpath -m ''{2}/'') ; export PATH=$(cygpath -u ''{3}/bin''):$PATH ; export CABAL_DIR=''{5}'' ; trap ''echo Press any key to exit && read -n 1 && exit'' 2 ; [[ ''{0}'' = https* ]] && {11} {0} | bash || cat $(cygpath -m ''{0}'') | bash ; echo ''Press any key to exit'' && read -n 1' -f $BootstrapUrl, $MsysDir, $GhcupBasePrefix, $GhcupDir, $SilentExport, $CabalDirFull, $StackInstallExport, $HLSInstallExport, $AdjustCabalConfigExport, $MinimalExport, $BootstrapDownloader, $DownloadScript) } # SIG # Begin signature block # MIID4QYJKoZIhvcNAQcCoIID0jCCA84CAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUVqKek181kF/Jx/P7z176herc # ZyCgggH/MIIB+zCCAWSgAwIBAgIQGOezhGS1A5tHh9VubW0liDANBgkqhkiG9w0B # AQUFADAYMRYwFAYDVQQDDA1KdWxpYW4gT3NwYWxkMB4XDTIxMDUzMDE4Mzk1OVoX # DTI1MDUzMDAwMDAwMFowGDEWMBQGA1UEAwwNSnVsaWFuIE9zcGFsZDCBnzANBgkq # hkiG9w0BAQEFAAOBjQAwgYkCgYEAs76XCXYPM14buR1RkVKhOB8pyM4Df6kPaz75 # nkbA0nq1VmMhBfCYFWyYHd7jniqTH0LoAKGGquN1bniREaCP9j2pFWpMIgLpQH3H # +jpsfmxV2BTG8q+Jok88gTXS1FlAk72E85zO/Jhr6Fja1aFYAdibBRsRxcVMTVh7 # 4AGLNGUCAwEAAaNGMEQwEwYDVR0lBAwwCgYIKwYBBQUHAwMwHQYDVR0OBBYEFC+R # hdhPo0Ty5HnzHyo1pN35IfZQMA4GA1UdDwEB/wQEAwIHgDANBgkqhkiG9w0BAQUF # AAOBgQAl3IdBVIwbJJDp7BksMYPeM4ivB3UyNvlw8aVxGwAzNgdSaezYIdMFtKXV # CSv5bd4VnFRAPDJW9dhW0h3SkeJUoklUxMjKXhR3qygQhSxPDjIatAuOCffGACba # ZZ7Om40b+pKXc6i/HnlApk9DGbXJ59bFcLGGcZ9QjoUae6Ex1DGCAUwwggFIAgEB # MCwwGDEWMBQGA1UEAwwNSnVsaWFuIE9zcGFsZAIQGOezhGS1A5tHh9VubW0liDAJ # BgUrDgMCGgUAoHgwGAYKKwYBBAGCNwIBDDEKMAigAoAAoQKAADAZBgkqhkiG9w0B # CQMxDAYKKwYBBAGCNwIBBDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAj # BgkqhkiG9w0BCQQxFgQUosm9nN1JgajqSBa1cUwxxhLrAsYwDQYJKoZIhvcNAQEB # BQAEgYCnKzfsH1aDjS6xkC/uymjaBowHSnh6nFu2AkjcKu8RgcBZzP5SLBXgU9wm # aED5Ujwyq3Qre+TGVRUqwkEauDhQiX2A008G00fRO6+di6yJRCRn5eaRAbdU3Xww # E5VhEwLBnwzWrvLKtdEclhgUCo5Tq87QMXVdgX4aRmunl4ZE+Q== # SIG # End signature block