From 96bcbbeeec74ed4fbf3c9dda718a347c874b70a0 Mon Sep 17 00:00:00 2001 From: Julian Ospald Date: Mon, 7 Jun 2021 20:39:51 +0200 Subject: [PATCH 01/12] Update CI --- .gitlab-ci.yml | 62 +++++++++++++++++++++----------------------------- 1 file changed, 26 insertions(+), 36 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 62abb41..3482f01 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -199,7 +199,7 @@ test:linux:bootstrap_script: script: - ./.gitlab/script/ghcup_bootstrap.sh variables: - GHC_VERSION: "8.10.4" + GHC_VERSION: "8.10.5" CABAL_VERSION: "3.4.0.0" extends: - .debian @@ -211,7 +211,7 @@ test:linux:recommended: stage: test extends: .test_ghcup_version:linux variables: - GHC_VERSION: "8.10.4" + GHC_VERSION: "8.10.5" CABAL_VERSION: "3.4.0.0" needs: [] @@ -219,7 +219,7 @@ test:linux:latest: stage: test extends: .test_ghcup_version:linux variables: - GHC_VERSION: "8.10.4" + GHC_VERSION: "9.0.1" CABAL_VERSION: "3.4.0.0" needs: [] @@ -229,7 +229,7 @@ test:linux:recommended:32bit: stage: test extends: .test_ghcup_version:linux32 variables: - GHC_VERSION: "8.10.4" + GHC_VERSION: "8.10.5" CABAL_VERSION: "3.2.0.0" needs: [] @@ -239,7 +239,7 @@ test:linux:recommended:armv7: stage: test extends: .test_ghcup_version:armv7 variables: - GHC_VERSION: "8.10.4" + GHC_VERSION: "8.10.5" CABAL_VERSION: "3.4.0.0" when: manual needs: [] @@ -248,7 +248,7 @@ test:linux:recommended:aarch64: stage: test extends: .test_ghcup_version:aarch64 variables: - GHC_VERSION: "8.10.4" + GHC_VERSION: "8.10.5" CABAL_VERSION: "3.4.0.0" when: manual needs: [] @@ -259,7 +259,7 @@ test:mac:recommended: stage: test extends: .test_ghcup_version:darwin variables: - GHC_VERSION: "8.10.4" + GHC_VERSION: "8.10.5" CABAL_VERSION: "3.4.0.0" needs: [] @@ -267,17 +267,17 @@ test:mac:latest: stage: test extends: .test_ghcup_version:darwin variables: - GHC_VERSION: "8.10.4" + GHC_VERSION: "9.0.1" CABAL_VERSION: "3.4.0.0" needs: [] -test:mac:recommended:aarch64: - stage: test - extends: .test_ghcup_version:darwin:aarch64 - variables: - GHC_VERSION: "8.10.5" - CABAL_VERSION: "3.4.0.0" - needs: [] +# test:mac:recommended:aarch64: + # stage: test + # extends: .test_ghcup_version:darwin:aarch64 + # variables: + # GHC_VERSION: "8.10.5" + # CABAL_VERSION: "3.4.0.0" + # needs: [] ######## freebsd test ######## @@ -286,17 +286,7 @@ test:freebsd:recommended: stage: test extends: .test_ghcup_version:freebsd variables: - GHC_VERSION: "8.10.4" - CABAL_VERSION: "3.4.0.0" - allow_failure: true # freebsd runners are unreliable - when: manual - needs: [] - -test:freebsd:latest: - stage: test - extends: .test_ghcup_version:freebsd - variables: - GHC_VERSION: "8.10.4" + GHC_VERSION: "8.10.5" CABAL_VERSION: "3.4.0.0" allow_failure: true # freebsd runners are unreliable when: manual @@ -308,7 +298,7 @@ test:windows:recommended: stage: test extends: .test_ghcup_version:windows variables: - GHC_VERSION: "8.10.4" + GHC_VERSION: "8.10.5" CABAL_VERSION: "3.4.0.0" needs: [] @@ -324,7 +314,7 @@ release:linux:64bit: - ./.gitlab/before_script/linux/alpine/install_deps.sh variables: ARTIFACT: "x86_64-linux-ghcup" - GHC_VERSION: "8.10.4" + GHC_VERSION: "8.10.5" CABAL_VERSION: "3.4.0.0" @@ -338,7 +328,7 @@ release:linux:32bit: - ./.gitlab/before_script/linux/alpine/install_deps.sh variables: ARTIFACT: "i386-linux-ghcup" - GHC_VERSION: "8.10.4" + GHC_VERSION: "8.10.5" CABAL_VERSION: "3.2.0.0" release:linux:armv7: @@ -351,7 +341,7 @@ release:linux:armv7: - ./.gitlab/before_script/linux/install_deps_manual.sh variables: ARTIFACT: "armv7-linux-ghcup" - GHC_VERSION: "8.10.4" + GHC_VERSION: "8.10.5" CABAL_VERSION: "3.4.0.0" release:linux:aarch64: @@ -364,7 +354,7 @@ release:linux:aarch64: - ./.gitlab/before_script/linux/install_deps_manual.sh variables: ARTIFACT: "aarch64-linux-ghcup" - GHC_VERSION: "8.10.4" + GHC_VERSION: "8.10.5" CABAL_VERSION: "3.4.0.0" ######## darwin release ######## @@ -380,7 +370,7 @@ release:darwin: - ./.gitlab/before_script/darwin/install_deps.sh variables: ARTIFACT: "x86_64-apple-darwin-ghcup" - GHC_VERSION: "8.10.4" + GHC_VERSION: "8.10.5" CABAL_VERSION: "3.4.0.0" MACOSX_DEPLOYMENT_TARGET: "10.7" @@ -389,7 +379,7 @@ release:darwin: release:freebsd: stage: release - needs: ["test:freebsd:recommended", "test:freebsd:latest"] + needs: ["test:freebsd:recommended"] extends: - .freebsd - .release_ghcup @@ -398,7 +388,7 @@ release:freebsd: - ./.gitlab/before_script/freebsd/install_deps.sh variables: ARTIFACT: "x86_64-portbld-freebsd-ghcup" - GHC_VERSION: "8.10.4" + GHC_VERSION: "8.10.5" CABAL_VERSION: "3.4.0.0" ######## windows release ######## @@ -414,7 +404,7 @@ release:windows: - bash ./.gitlab/before_script/windows/install_deps.sh variables: ARTIFACT: "x86_64-mingw64-ghcup" - GHC_VERSION: "8.10.4" + GHC_VERSION: "8.10.5" CABAL_VERSION: "3.4.0.0" ######## hlint ######## @@ -428,7 +418,7 @@ hlint: script: - ./.gitlab/script/hlint.sh variables: - GHC_VERSION: "8.10.4" + GHC_VERSION: "8.10.5" CABAL_VERSION: "3.4.0.0" JSON_VERSION: "0.0.4" allow_failure: true From 27510b3b51b1216634073882d68dd4dd010ac824 Mon Sep 17 00:00:00 2001 From: Julian Ospald Date: Tue, 8 Jun 2021 13:57:01 +0200 Subject: [PATCH 02/12] Allow setting GHCUP_INSTALL_BASE_PREFIX on windows --- bootstrap-haskell | 8 ++-- bootstrap-haskell.ps1 | 90 +++++++++++++++++++++++++++++------------ lib/GHCup/Utils/Dirs.hs | 15 ++++--- 3 files changed, 75 insertions(+), 38 deletions(-) diff --git a/bootstrap-haskell b/bootstrap-haskell index acf1aad..d25a492 100755 --- a/bootstrap-haskell +++ b/bootstrap-haskell @@ -22,8 +22,8 @@ base_url="https://downloads.haskell.org/~ghcup" case "${plat}" in MSYS*|MINGW*) : "${GHCUP_INSTALL_BASE_PREFIX:=/c}" - GHCUP_DIR=${GHCUP_INSTALL_BASE_PREFIX}/ghcup - GHCUP_BIN=${GHCUP_INSTALL_BASE_PREFIX}/ghcup/bin + GHCUP_DIR=$(cygpath -u "${GHCUP_INSTALL_BASE_PREFIX}/ghcup") + GHCUP_BIN=$(cygpath -u "${GHCUP_INSTALL_BASE_PREFIX}/ghcup/bin") : "${GHCUP_MSYS2:=${GHCUP_DIR}/msys64}" ;; *) @@ -177,7 +177,7 @@ download_ghcup() { MSYS*|MINGW*) case "${arch}" in x86_64|amd64) - _url=https://downloads.haskell.org/ghcup/0.1.15-rc2/x86_64-mingw64-ghcup-0.1.15.exe + _url=https://downloads.haskell.org/~ghcup/tmp/x86_64-mingw64-ghcup-9.exe ;; *) die "Unknown architecture: ${arch}" ;; @@ -273,7 +273,7 @@ eghcup set ghc "${BOOTSTRAP_HASKELL_GHC_VERSION}" eghcup --cache install cabal "${BOOTSTRAP_HASKELL_CABAL_VERSION}" adjust_cabal_config() { - edo cabal user-config -a "extra-prog-path: $(cygpath -w $GHCUP_BIN), $(cygpath -w "$HOME"/AppData/Roaming/cabal/bin), $(cygpath -w "$GHCUP_MSYS2"/usr/bin), $(cygpath -w "$GHCUP_MSYS2"/mingw64/bin)" -a "extra-include-dirs: $(cygpath -w "$GHCUP_MSYS2"/mingw64/include)" -a "extra-lib-dirs: $(cygpath -w "$GHCUP_MSYS2"/mingw64/lib)" -f init + edo cabal user-config -a "extra-prog-path: $(cygpath -w "$GHCUP_BIN"), $(cygpath -w "$HOME"/AppData/Roaming/cabal/bin), $(cygpath -w "$GHCUP_MSYS2"/usr/bin), $(cygpath -w "$GHCUP_MSYS2"/mingw64/bin)" -a "extra-include-dirs: $(cygpath -w "$GHCUP_MSYS2"/mingw64/include)" -a "extra-lib-dirs: $(cygpath -w "$GHCUP_MSYS2"/mingw64/lib)" -f init } case "${plat}" in diff --git a/bootstrap-haskell.ps1 b/bootstrap-haskell.ps1 index d91ad52..71a91a4 100644 --- a/bootstrap-haskell.ps1 +++ b/bootstrap-haskell.ps1 @@ -91,9 +91,47 @@ function Get-FileWCSynchronous{ Get-Item -Path $destination | Unblock-File } +function Test-AbsolutePath { + Param ( + [Parameter(Mandatory=$True)] + [ValidateScript({[System.IO.Path]::IsPathRooted($_)})] + [String]$Path + ) +} + $ErrorActionPreference = 'Stop' -$GhcupDir = "C:\ghcup" +$GhcupBasePrefix = [System.Environment]::GetEnvironmentVariable('GHCUP_INSTALL_BASE_PREFIX', 'user') + +if ($GhcupBasePrefix) { + $defaultGhcupBasePrefix = $GhcupBasePrefix +} else { + $defaultGhcupBasePrefix = 'C:\' +} + +while ($true) { + Print-Msg -color Magenta -msg ('Where to install to (this should be a short Path, preferably a Drive like ''C:\''){1}Press enter to accept the default [{0}]:' -f $defaultGhcupBasePrefix, "`n") + $basePrefixPrompt = Read-Host + $GhcupBasePrefix = ($defaultGhcupBasePrefix,$basePrefixPrompt)[[bool]$basePrefixPrompt] + if (!($GhcupBasePrefix.EndsWith('\'))) { + $GhcupBasePrefix = ('{0}\' -f $GhcupBasePrefix) + } + + 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) $MsysDir = ('{0}\msys64' -f $GhcupDir) $Bash = ('{0}\usr\bin\bash' -f $MsysDir) $BootstrapUrl = 'https://www.haskell.org/ghcup/sh/bootstrap-haskell-windows' @@ -101,7 +139,7 @@ $GhcupMsys2 = [System.Environment]::GetEnvironmentVariable('GHCUP_MSYS2', 'user' Print-Msg -msg 'Preparing for GHCup installation...' -if (Test-Path -Path ('{0}' -f $GhcupDir)) { +if (Test-Path -LiteralPath ('{0}' -f $GhcupDir)) { $decision = $Host.UI.PromptForChoice('Install GHCup' , 'GHCup is already installed, what do you want to do?' , @('&Reinstall' @@ -124,7 +162,7 @@ $null = New-Item -Path ('{0}' -f $GhcupDir) -Name 'bin' -ItemType 'directory' -E Print-Msg -msg 'First checking for Msys2...' -if (!(Test-Path -Path ('{0}' -f $MsysDir)) -And !($GhcupMsys2)) { +if (!(Test-Path -Path ('{0}' -f $MsysDir))) { $msys2Decision = $Host.UI.PromptForChoice('Install MSys2' , 'Do you want GHCup to install a default MSys2 toolchain (recommended)?' , @('&Yes' @@ -166,31 +204,31 @@ if (!(Test-Path -Path ('{0}' -f $MsysDir)) -And !($GhcupMsys2)) { Print-Msg -msg 'Setting default home directory...' & "$Bash" -lc "sed -i -e 's/db_home:.*$/db_home: windows/' /etc/nsswitch.conf" } elseif ($msys2Decision -eq 1) { - Print-Msg -color Magenta -msg 'Skipping MSys2 installation.' - if ($GhcupMsys2) { - Print-Msg -msg 'GHCUP_MSYS2 env var set, using existing installation...' - $MsysDir = $GhcupMsys2 - } else { - $MsysDir = Read-Host -Prompt 'Input existing MSys2 toolchain directory' + Print-Msg -color Yellow -msg 'Skipping MSys2 installation.' + while ($true) { + if ($GhcupMsys2) { + $defaultMsys2Dir = $GhcupMsys2 + Print-Msg -color Magenta -msg ('Input existing MSys2 toolchain directory. Press enter to accept the default [{0}]:' -f $defaultMsys2Dir) + $MsysDirPrompt = Read-Host + $MsysDir = ($defaultMsys2Dir,$MsysDirPrompt)[[bool]$MsysDirPrompt] + } else { + Print-Msg -color Magenta -msg 'Input existing MSys2 toolchain directory:' + $MsysDir = Read-Host + } + 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 + } } - - if (!(Test-Path -Path ('{0}' -f $MsysDir))) { - Print-Msg -color Red -msg ('MSys2 installation at ''{0}'' could not be found, aborting!' -f $MsysDir) - Break - } - Print-Msg -msg 'Making MSys2 discoverable for GHCup...' + 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) } -} elseif ($GhcupMsys2) { - if (!(Test-Path -Path ('{0}' -f $GhcupMsys2))) { - Print-Msg -color Red -msg ('MSys2 installation at ''{0}'' could not be found, aborting!' -f $GhcupMsys2) - Break - } - $MsysDir = $GhcupMsys2 - Print-Msg -msg 'Making MSys2 discoverable for GHCup...' - $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) } @@ -207,9 +245,9 @@ Print-Msg -msg 'Starting GHCup installer...' $Msys2Shell = ('{0}\msys2_shell.cmd' -f $MsysDir) if ((Get-Process -ID $PID).ProcessName.StartsWith("bootstrap-haskell")) { - & "$Bash" -lc ('[ -n ''{1}'' ] && export GHCUP_MSYS2=$(cygpath -w ''{1}'') ; export PATH="/c/ghcup/bin:$PATH" ; curl --proto ''=https'' --tlsv1.2 -sSf {0} | bash' -f $BootstrapUrl, $MsysDir) + & "$Bash" -lc ('[ -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 ; curl --proto ''=https'' --tlsv1.2 -sSf {0} | bash' -f $BootstrapUrl, $MsysDir, $GhcupBasePrefix, $GhcupDir) } else { - & "$Msys2Shell" -mingw64 -mintty -c ('[ -n ''{1}'' ] && export GHCUP_MSYS2=$(cygpath -w ''{1}'') ; export PATH="/c/ghcup/bin:$PATH" ; trap ''echo Press any key to exit && read -n 1 && exit'' 2 ; curl --proto =https --tlsv1.2 -sSf -k {0} | bash ; echo ''Press any key to exit'' && read -n 1' -f $BootstrapUrl, $MsysDir) + & "$Msys2Shell" -mingw64 -mintty -c ('[ -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 ; trap ''echo Press any key to exit && read -n 1 && exit'' 2 ; curl --proto =https --tlsv1.2 -sSf -k {0} | bash ; echo ''Press any key to exit'' && read -n 1' -f $BootstrapUrl, $MsysDir, $GhcupBasePrefix, $GhcupDir) } diff --git a/lib/GHCup/Utils/Dirs.hs b/lib/GHCup/Utils/Dirs.hs index 7e256a1..ba90660 100644 --- a/lib/GHCup/Utils/Dirs.hs +++ b/lib/GHCup/Utils/Dirs.hs @@ -47,14 +47,12 @@ import Data.Maybe import Data.String.Interpolate import GHC.IO.Exception ( IOErrorType(NoSuchThing) ) import Haskus.Utils.Variant.Excepts -#if !defined(IS_WINDOWS) import Optics +#if !defined(IS_WINDOWS) import System.Directory #endif import System.DiskSpace -#if !defined(IS_WINDOWS) import System.Environment -#endif import System.FilePath import System.IO.Temp @@ -78,7 +76,8 @@ import Control.Concurrent (threadDelay) ghcupBaseDir :: IO FilePath ghcupBaseDir = do #if defined(IS_WINDOWS) - pure ("C:\\" "ghcup") + bdir <- fromMaybe "C:\\" <$> lookupEnv "GHCUP_INSTALL_BASE_PREFIX" + pure (bdir "ghcup") #else xdg <- useXDG if xdg @@ -104,7 +103,7 @@ ghcupBaseDir = do ghcupConfigDir :: IO FilePath ghcupConfigDir = do #if defined(IS_WINDOWS) - pure ("C:\\" "ghcup") + ghcupBaseDir #else xdg <- useXDG if xdg @@ -129,7 +128,7 @@ ghcupConfigDir = do ghcupBinDir :: IO FilePath ghcupBinDir = do #if defined(IS_WINDOWS) - pure ("C:\\" "ghcup" "bin") + ghcupBaseDir <&> ( "bin") #else xdg <- useXDG if xdg @@ -150,7 +149,7 @@ ghcupBinDir = do ghcupCacheDir :: IO FilePath ghcupCacheDir = do #if defined(IS_WINDOWS) - pure ("C:\\" "ghcup" "cache") + ghcupBaseDir <&> ( "cache") #else xdg <- useXDG if xdg @@ -172,7 +171,7 @@ ghcupCacheDir = do ghcupLogsDir :: IO FilePath ghcupLogsDir = do #if defined(IS_WINDOWS) - pure ("C:\\" "ghcup" "logs") + ghcupBaseDir <&> ( "logs") #else xdg <- useXDG if xdg From 860aa0dafd4cfc51abaf2115726711275248da49 Mon Sep 17 00:00:00 2001 From: Julian Ospald Date: Tue, 8 Jun 2021 23:46:20 +0200 Subject: [PATCH 03/12] Improvements to bootstrap scripts --- bootstrap-haskell | 17 ++-- bootstrap-haskell.ps1 | 214 ++++++++++++++++++++++++++++-------------- 2 files changed, 148 insertions(+), 83 deletions(-) diff --git a/bootstrap-haskell b/bootstrap-haskell index d25a492..412ec8d 100755 --- a/bootstrap-haskell +++ b/bootstrap-haskell @@ -415,17 +415,13 @@ if [ -z "${BOOTSTRAP_HASKELL_NONINTERACTIVE}" ] ; then case $MY_SHELL in "") break ;; fish) - if ! grep -q "ghcup-env" "${GHCUP_PROFILE_FILE}" ; then mkdir -p "${GHCUP_PROFILE_FILE%/*}" - echo "# ghcup-env" >> "${GHCUP_PROFILE_FILE}" - echo "set -q GHCUP_INSTALL_BASE_PREFIX[1]; or set GHCUP_INSTALL_BASE_PREFIX \$HOME" >> "${GHCUP_PROFILE_FILE}" - echo "test -f $GHCUP_DIR/env ; and set -gx PATH \$HOME/.cabal/bin $GHCUP_BIN \$PATH" >> "${GHCUP_PROFILE_FILE}" - fi + sed -i -e '/# ghcup-env$/ s/^#*/#/' "${GHCUP_PROFILE_FILE}" + echo "set -q GHCUP_INSTALL_BASE_PREFIX[1]; or set GHCUP_INSTALL_BASE_PREFIX \$HOME ; test -f $GHCUP_DIR/env ; and set -gx PATH \$HOME/.cabal/bin $GHCUP_BIN \$PATH # ghcup-env" >> "${GHCUP_PROFILE_FILE}" break ;; bash) - if ! grep -q "ghcup-env" "${GHCUP_PROFILE_FILE}" ; then - echo "[ -f \"${GHCUP_DIR}/env\" ] && source \"${GHCUP_DIR}/env\" # ghcup-env" >> "${GHCUP_PROFILE_FILE}" - fi + sed -i -e '/# ghcup-env$/ s/^#*/#/' "${GHCUP_PROFILE_FILE}" + echo "[ -f \"${GHCUP_DIR}/env\" ] && source \"${GHCUP_DIR}/env\" # ghcup-env" >> "${GHCUP_PROFILE_FILE}" case "${plat}" in "Darwin"|"darwin") if ! grep -q "ghcup-env" "${HOME}/.bash_profile" ; then @@ -436,9 +432,8 @@ if [ -z "${BOOTSTRAP_HASKELL_NONINTERACTIVE}" ] ; then break ;; zsh) - if ! grep -q "ghcup-env" "${GHCUP_PROFILE_FILE}" ; then - echo "[ -f \"${GHCUP_DIR}/env\" ] && source \"${GHCUP_DIR}/env\" # ghcup-env" >> "${GHCUP_PROFILE_FILE}" - fi + sed -i -e '/# ghcup-env$/ s/^#*/#/' "${GHCUP_PROFILE_FILE}" + echo "[ -f \"${GHCUP_DIR}/env\" ] && source \"${GHCUP_DIR}/env\" # ghcup-env" >> "${GHCUP_PROFILE_FILE}" break ;; esac warn "OK! ${GHCUP_PROFILE_FILE} has been modified. Restart your terminal for the changes to take effect," diff --git a/bootstrap-haskell.ps1 b/bootstrap-haskell.ps1 index 71a91a4..9045ecd 100644 --- a/bootstrap-haskell.ps1 +++ b/bootstrap-haskell.ps1 @@ -1,3 +1,30 @@ +<# + .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" +#> +param ( + # Run a non-interactive installation + [bool]$Silent = $false, + # Specify the install root (default: 'C:\') + [string]$InstallDir, + # Instead of installing a new MSys2, use an existing installation + [string]$ExistingMsys2Dir, + # Perform a quick installation, omitting some expensive operations (you may have to install dependencies yourself later) + [bool]$Quick, + # Overwrite (or rather backup) a previous install + [bool]$Overwrite +) + function Print-Msg { param ( [Parameter(Mandatory=$true, HelpMessage='String to output')][string]$msg, [string]$color = "Green" ) Write-Host ('{0}' -f $msg) -ForegroundColor $color @@ -15,51 +42,48 @@ function Create-Shortcut { } function Add-EnvPath { - param( - [Parameter(Mandatory=$true,HelpMessage='The Pathe to add to Users environment')] - [string] $Path, + param( + [Parameter(Mandatory=$true,HelpMessage='The Path to add to Users environment')] + [string] $Path, - [ValidateSet('Machine', 'User', 'Session')] - [string] $Container = 'Session' - ) + [ValidateSet('Machine', 'User', 'Session')] + [string] $Container = 'Session' + ) - function Where-Something - { - param - ( - [Parameter(Mandatory=$true, ValueFromPipeline=$true, HelpMessage='Data to filter')] - $InputObject - ) - process - { - if ($InputObject) - { - $InputObject - } + 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' } } - } - if ($Container -ne 'Session') { - $containerMapping = @{ - Machine = [EnvironmentVariableTarget]::Machine - User = [EnvironmentVariableTarget]::User - } - $containerType = $containerMapping[$Container] + $hiveKey = $envKey = $null + try { + $hiveKey = [Microsoft.Win32.RegistryKey]::OpenBaseKey($hive, 'Default') + $envKey = $hiveKey.OpenSubKey($keyPath, $true) + $rawPath = $envKey.GetValue('PATH', '', 'DoNotExpandEnvironmentNames') - $persistedPaths = [Environment]::GetEnvironmentVariable('Path', $containerType) -split ';' - if ($persistedPaths -notcontains $Path) { - $persistedPaths = $persistedPaths + $Path | Where-Something - [Environment]::SetEnvironmentVariable('Path', $persistedPaths -join ';', $containerType) - } - } - - $envPaths = $env:Path -split ';' - if ($envPaths -notcontains $Path) { - $envPaths = $envPaths + $Path | Where-Something - $env:Path = $envPaths -join ';' - } + $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.Dispose() } + if ($hiveKey) { $hiveKey.Dispose() } + } + } } + + filter Get-FileSize { '{0:N2} {1}' -f $( if ($_ -lt 1kb) { $_, 'Bytes' } @@ -101,32 +125,47 @@ function Test-AbsolutePath { $ErrorActionPreference = 'Stop' -$GhcupBasePrefix = [System.Environment]::GetEnvironmentVariable('GHCUP_INSTALL_BASE_PREFIX', 'user') +$GhcupBasePrefixEnv = [System.Environment]::GetEnvironmentVariable('GHCUP_INSTALL_BASE_PREFIX', 'user') -if ($GhcupBasePrefix) { - $defaultGhcupBasePrefix = $GhcupBasePrefix +if ($GhcupBasePrefixEnv) { + $defaultGhcupBasePrefix = $GhcupBasePrefixEnv } else { $defaultGhcupBasePrefix = 'C:\' } -while ($true) { - Print-Msg -color Magenta -msg ('Where to install to (this should be a short Path, preferably a Drive like ''C:\''){1}Press enter to accept the default [{0}]:' -f $defaultGhcupBasePrefix, "`n") - $basePrefixPrompt = Read-Host - $GhcupBasePrefix = ($defaultGhcupBasePrefix,$basePrefixPrompt)[[bool]$basePrefixPrompt] - if (!($GhcupBasePrefix.EndsWith('\'))) { - $GhcupBasePrefix = ('{0}\' -f $GhcupBasePrefix) - } - - 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" +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!" + Exit 1 + } elseif (!(Split-Path -IsAbsolute -Path "$InstallDir")) { + Print-Msg -color Red -msg "Non-absolute Path specified!" + Exit 1 } else { - Break + $GhcupBasePrefix = $InstallDir + } +} else { + while ($true) { + Print-Msg -color Magenta -msg ('Where to install to (this should be a short Path, preferably a Drive like ''C:\''){1}Press enter to accept the default [{0}]:' -f $defaultGhcupBasePrefix, "`n") + $basePrefixPrompt = Read-Host + $GhcupBasePrefix = ($defaultGhcupBasePrefix,$basePrefixPrompt)[[bool]$basePrefixPrompt] + if (!($GhcupBasePrefix.EndsWith('\'))) { + $GhcupBasePrefix = ('{0}\' -f $GhcupBasePrefix) + } + + 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) @@ -140,11 +179,19 @@ $GhcupMsys2 = [System.Environment]::GetEnvironmentVariable('GHCUP_MSYS2', 'user' Print-Msg -msg 'Preparing for GHCup installation...' if (Test-Path -LiteralPath ('{0}' -f $GhcupDir)) { - $decision = $Host.UI.PromptForChoice('Install GHCup' - , 'GHCup is already installed, what do you want to do?' - , @('&Reinstall' - '&Continue' - '&Abort'), 1) + 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?' + , @('&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) @@ -152,7 +199,7 @@ if (Test-Path -LiteralPath ('{0}' -f $GhcupDir)) { } elseif ($decision -eq 1) { Print-Msg -msg 'Continuing installation...' } elseif ($decision -eq 2) { - Break + Exit 0 } } @@ -163,10 +210,15 @@ $null = New-Item -Path ('{0}' -f $GhcupDir) -Name 'bin' -ItemType 'directory' -E Print-Msg -msg 'First checking for Msys2...' if (!(Test-Path -Path ('{0}' -f $MsysDir))) { - $msys2Decision = $Host.UI.PromptForChoice('Install MSys2' - , 'Do you want GHCup to install a default MSys2 toolchain (recommended)?' - , @('&Yes' - '&No'), 0) + if ($Silent) { + $msys2Decision = 0 + } else { + $msys2Decision = $Host.UI.PromptForChoice('Install MSys2' + , 'Do you want GHCup to install a default MSys2 toolchain (recommended)?' + , @('&Yes' + '&No'), 0) + } + if ($msys2Decision -eq 0) { Print-Msg -msg ('...Msys2 doesn''t exist, installing into {0} ...this may take a while' -f $MsysDir) @@ -195,8 +247,20 @@ if (!(Test-Path -Path ('{0}' -f $MsysDir))) { Print-Msg -msg 'Upgrading full system twice...' & "$Bash" -lc 'pacman --noconfirm -Syuu' - Print-Msg -msg 'Installing GHC Build Dependencies...' - & "$Bash" -lc 'pacman --noconfirm -S --needed git tar curl wget base-devel gettext binutils autoconf make libtool automake python p7zip patch unzip mingw-w64-x86_64-toolchain mingw-w64-x86_64-gcc mingw-w64-x86_64-gdb mingw-w64-x86_64-python2 mingw-w64-x86_64-python3-sphinx' + if ($Quick) { + $ghcBuildDeps = $Quick + } elseif (!($Silent)) { + $ghcBuildDeps = $Host.UI.PromptForChoice('Install Dependencies' + , 'Install various dependencies to be able to build GHC itself and make use of ''ghcup compile'' command? (recommended, however this might take a while)' + , @('&Yes' + '&No'), 0) + } else { + $ghcBuildDeps = 0 + } + if ($ghcBuildDeps -eq 0) { + Print-Msg -msg 'Installing GHC Build Dependencies...' + & "$Bash" -lc 'pacman --noconfirm -S --needed git tar curl wget base-devel gettext binutils autoconf make libtool automake python p7zip patch unzip mingw-w64-x86_64-toolchain mingw-w64-x86_64-gcc mingw-w64-x86_64-gdb mingw-w64-x86_64-python2 mingw-w64-x86_64-python3-sphinx' + } Print-Msg -msg 'Updating SSL root certificate authorities...' & "$Bash" -lc 'pacman --noconfirm -S ca-certificates' @@ -238,16 +302,22 @@ Create-Shortcut -SourceExe ('{0}\msys2_shell.cmd' -f $MsysDir) -ArgumentsToSourc Create-Shortcut -SourceExe 'https://www.msys2.org/docs/package-management' -ArgumentsToSourceExe '' -DestinationPath ('{0}\Desktop\Mingw package management docs.url' -f $HOME) Print-Msg -msg ('Adding {0}\bin to Users Path...' -f $GhcupDir) -Add-EnvPath -Path ('{0}\bin' -f $GhcupDir) -Container 'User' +Add-EnvPath -Path ('{0}\bin' -f ([System.IO.Path]::GetFullPath("$GhcupDir"))) -Container 'User' Print-Msg -msg 'Starting GHCup installer...' $Msys2Shell = ('{0}\msys2_shell.cmd' -f $MsysDir) -if ((Get-Process -ID $PID).ProcessName.StartsWith("bootstrap-haskell")) { - & "$Bash" -lc ('[ -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 ; curl --proto ''=https'' --tlsv1.2 -sSf {0} | bash' -f $BootstrapUrl, $MsysDir, $GhcupBasePrefix, $GhcupDir) +if ($Silent) { + $SilentExport = 'export BOOTSTRAP_HASKELL_NONINTERACTIVE=1 ;' } else { - & "$Msys2Shell" -mingw64 -mintty -c ('[ -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 ; trap ''echo Press any key to exit && read -n 1 && exit'' 2 ; curl --proto =https --tlsv1.2 -sSf -k {0} | bash ; echo ''Press any key to exit'' && read -n 1' -f $BootstrapUrl, $MsysDir, $GhcupBasePrefix, $GhcupDir) + $SilentExport = '' +} + +if ((Get-Process -ID $PID).ProcessName.StartsWith("bootstrap-haskell")) { + & "$Bash" -lc ('{4} [ -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 ; curl --proto ''=https'' --tlsv1.2 -sSf {0} | bash' -f $BootstrapUrl, $MsysDir, $GhcupBasePrefix, $GhcupDir, $SilentExport) +} else { + & "$Msys2Shell" -mingw64 -mintty -c ('{4} [ -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 ; trap ''echo Press any key to exit && read -n 1 && exit'' 2 ; curl --proto =https --tlsv1.2 -sSf -k {0} | bash ; echo ''Press any key to exit'' && read -n 1' -f $BootstrapUrl, $MsysDir, $GhcupBasePrefix, $GhcupDir, $SilentExport) } From f80638bba4235c2e4c31c2a52951d627b90fb243 Mon Sep 17 00:00:00 2001 From: Julian Ospald Date: Wed, 9 Jun 2021 14:43:36 +0200 Subject: [PATCH 04/12] Improve error handling --- bootstrap-haskell.ps1 | 39 +++++++++++++++++++++++++++++---------- 1 file changed, 29 insertions(+), 10 deletions(-) diff --git a/bootstrap-haskell.ps1 b/bootstrap-haskell.ps1 index 9045ecd..bf7f095 100644 --- a/bootstrap-haskell.ps1 +++ b/bootstrap-haskell.ps1 @@ -123,6 +123,25 @@ function Test-AbsolutePath { ) } +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') @@ -227,7 +246,7 @@ if (!(Test-Path -Path ('{0}' -f $MsysDir))) { $archive = 'msys2-x86_64-latest.sfx.exe' if (Get-Command -Name 'curl.exe' -ErrorAction SilentlyContinue) { - curl.exe -o ('{0}\{1}' -f $env:TEMP, $archive) ('https://repo.msys2.org/distrib/{0}' -f $archive) + Exec "curl.exe" '-o' ('{0}\{1}' -f $env:TEMP, $archive) ('https://repo.msys2.org/distrib/{0}' -f $archive) } else { Get-FileWCSynchronous -url ('https://repo.msys2.org/distrib/{0}' -f $archive) -destinationFolder "$env:TEMP" -includeStats } @@ -237,15 +256,15 @@ if (!(Test-Path -Path ('{0}' -f $MsysDir))) { Remove-Item -Path ('{0}/{1}' -f $env:TEMP, $archive) Print-Msg -msg 'Processing MSYS2 bash for first time use...' - & "$Bash" -lc 'exit' + Exec "$Bash" '-lc' 'exit' - & "$env:windir\system32\taskkill.exe" /F /FI `"MODULES eq msys-2.0.dll`" + Exec "$env:windir\system32\taskkill.exe" /F /FI `"MODULES eq msys-2.0.dll`" Print-Msg -msg 'Upgrading full system...' - & "$Bash" -lc 'pacman --noconfirm -Syuu' + Exec "$Bash" '-lc' 'pacman --noconfirm -Syuu' Print-Msg -msg 'Upgrading full system twice...' - & "$Bash" -lc 'pacman --noconfirm -Syuu' + Exec "$Bash" '-lc' 'pacman --noconfirm -Syuu' if ($Quick) { $ghcBuildDeps = $Quick @@ -259,14 +278,14 @@ if (!(Test-Path -Path ('{0}' -f $MsysDir))) { } if ($ghcBuildDeps -eq 0) { Print-Msg -msg 'Installing GHC Build Dependencies...' - & "$Bash" -lc 'pacman --noconfirm -S --needed git tar curl wget base-devel gettext binutils autoconf make libtool automake python p7zip patch unzip mingw-w64-x86_64-toolchain mingw-w64-x86_64-gcc mingw-w64-x86_64-gdb mingw-w64-x86_64-python2 mingw-w64-x86_64-python3-sphinx' + Exec "$Bash" '-lc' 'pacman --noconfirm -S --needed git tar curl wget base-devel gettext binutils autoconf make libtool automake python p7zip patch unzip mingw-w64-x86_64-toolchain mingw-w64-x86_64-gcc mingw-w64-x86_64-gdb mingw-w64-x86_64-python2 mingw-w64-x86_64-python3-sphinx' } Print-Msg -msg 'Updating SSL root certificate authorities...' - & "$Bash" -lc 'pacman --noconfirm -S ca-certificates' + Exec "$Bash" '-lc' 'pacman --noconfirm -S ca-certificates' Print-Msg -msg 'Setting default home directory...' - & "$Bash" -lc "sed -i -e 's/db_home:.*$/db_home: windows/' /etc/nsswitch.conf" + 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) { @@ -315,9 +334,9 @@ if ($Silent) { } if ((Get-Process -ID $PID).ProcessName.StartsWith("bootstrap-haskell")) { - & "$Bash" -lc ('{4} [ -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 ; curl --proto ''=https'' --tlsv1.2 -sSf {0} | bash' -f $BootstrapUrl, $MsysDir, $GhcupBasePrefix, $GhcupDir, $SilentExport) + Exec "$Bash" '-lc' ('{4} [ -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 ; curl --proto ''=https'' --tlsv1.2 -sSf {0} | bash' -f $BootstrapUrl, $MsysDir, $GhcupBasePrefix, $GhcupDir, $SilentExport) } else { - & "$Msys2Shell" -mingw64 -mintty -c ('{4} [ -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 ; trap ''echo Press any key to exit && read -n 1 && exit'' 2 ; curl --proto =https --tlsv1.2 -sSf -k {0} | bash ; echo ''Press any key to exit'' && read -n 1' -f $BootstrapUrl, $MsysDir, $GhcupBasePrefix, $GhcupDir, $SilentExport) + Exec "$Msys2Shell" '-mingw64' '-mintty' '-c' ('{4} [ -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 ; trap ''echo Press any key to exit && read -n 1 && exit'' 2 ; curl --proto =https --tlsv1.2 -sSf -k {0} | bash ; echo ''Press any key to exit'' && read -n 1' -f $BootstrapUrl, $MsysDir, $GhcupBasePrefix, $GhcupDir, $SilentExport) } From 2c077db36ba58bbb3f9599a93cb1f83f0c76b5f2 Mon Sep 17 00:00:00 2001 From: Julian Ospald Date: Wed, 9 Jun 2021 14:43:48 +0200 Subject: [PATCH 05/12] Improve portability --- bootstrap-haskell.ps1 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bootstrap-haskell.ps1 b/bootstrap-haskell.ps1 index bf7f095..3cd1a9a 100644 --- a/bootstrap-haskell.ps1 +++ b/bootstrap-haskell.ps1 @@ -204,7 +204,7 @@ if (Test-Path -LiteralPath ('{0}' -f $GhcupDir)) { } elseif (!($Silent)) { $decision = $Host.UI.PromptForChoice('Install GHCup' , 'GHCup is already installed, what do you want to do?' - , @('&Reinstall' + , [System.Management.Automation.Host.ChoiceDescription[]] @('&Reinstall' '&Continue' '&Abort'), 1) } else { @@ -234,7 +234,7 @@ if (!(Test-Path -Path ('{0}' -f $MsysDir))) { } else { $msys2Decision = $Host.UI.PromptForChoice('Install MSys2' , 'Do you want GHCup to install a default MSys2 toolchain (recommended)?' - , @('&Yes' + , [System.Management.Automation.Host.ChoiceDescription[]] @('&Yes' '&No'), 0) } @@ -271,7 +271,7 @@ if (!(Test-Path -Path ('{0}' -f $MsysDir))) { } elseif (!($Silent)) { $ghcBuildDeps = $Host.UI.PromptForChoice('Install Dependencies' , 'Install various dependencies to be able to build GHC itself and make use of ''ghcup compile'' command? (recommended, however this might take a while)' - , @('&Yes' + , [System.Management.Automation.Host.ChoiceDescription[]] @('&Yes' '&No'), 0) } else { $ghcBuildDeps = 0 From 468fc5ade99a1fd4a949a98e267efc75b9dc8e8a Mon Sep 17 00:00:00 2001 From: Julian Ospald Date: Wed, 9 Jun 2021 15:02:11 +0200 Subject: [PATCH 06/12] Use absolute ghcup binary path --- bootstrap-haskell | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bootstrap-haskell b/bootstrap-haskell index 412ec8d..d077bc2 100755 --- a/bootstrap-haskell +++ b/bootstrap-haskell @@ -73,9 +73,9 @@ _eghcup() { args="-s ${BOOTSTRAP_HASKELL_YAML}" fi if [ -z "${BOOTSTRAP_HASKELL_VERBOSE}" ] ; then - ghcup ${args} "$@" + "${GHCUP_BIN}/ghcup" ${args} "$@" else - ghcup ${args} --verbose "$@" + "${GHCUP_BIN}/ghcup" ${args} --verbose "$@" fi } From fedc0bbef6bbec837529d0ab1af12d4d642e1c9a Mon Sep 17 00:00:00 2001 From: Julian Ospald Date: Wed, 9 Jun 2021 16:31:40 +0200 Subject: [PATCH 07/12] Debug --- .gitlab/before_script/windows/install_deps.sh | 5 ++--- .gitlab/ghcup_env | 2 +- .gitlab/script/ghcup_version.sh | 4 ++++ 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/.gitlab/before_script/windows/install_deps.sh b/.gitlab/before_script/windows/install_deps.sh index 3c22412..df06977 100644 --- a/.gitlab/before_script/windows/install_deps.sh +++ b/.gitlab/before_script/windows/install_deps.sh @@ -6,11 +6,10 @@ set -eux mkdir -p "${TMPDIR}" "${CABAL_DIR}" -rm -rf /c/ghcup -mkdir -p /c/ghcup +mkdir -p "$GHCUP_INSTALL_BASE_PREFIX/ghcup/bin" CI_PROJECT_DIR=$(pwd) -curl -o ghcup.exe https://downloads.haskell.org/~ghcup/tmp/x86_64-mingw64-ghcup-5.exe +curl -o ghcup.exe https://downloads.haskell.org/~ghcup/tmp/x86_64-mingw64-ghcup-9.exe chmod +x ghcup.exe ./ghcup.exe install ${GHC_VERSION} diff --git a/.gitlab/ghcup_env b/.gitlab/ghcup_env index 46d289e..0d99880 100644 --- a/.gitlab/ghcup_env +++ b/.gitlab/ghcup_env @@ -1,6 +1,6 @@ if [ "${OS}" = "WINDOWS" ] ; then export GHCUP_INSTALL_BASE_PREFIX="$CI_PROJECT_DIR" - export PATH="/c/ghcup/bin:$CI_PROJECT_DIR/.local/bin:$PATH" + export PATH="$GHCUP_INSTALL_BASE_PREFIX/ghcup/bin:$CI_PROJECT_DIR/.local/bin:$PATH" export TMPDIR="$CI_PROJECT_DIR/tmp" else export GHCUP_INSTALL_BASE_PREFIX="$CI_PROJECT_DIR" diff --git a/.gitlab/script/ghcup_version.sh b/.gitlab/script/ghcup_version.sh index 4274bed..a3d57b7 100755 --- a/.gitlab/script/ghcup_version.sh +++ b/.gitlab/script/ghcup_version.sh @@ -106,7 +106,11 @@ else # test wget a bit fi [ "$(ghc --numeric-version)" = "${ghc_ver}" ] eghcup set 8.10.3 +eghcup list +which ghc eghcup set 8.10.3 +eghcup list +which ghc [ "$(ghc --numeric-version)" = "8.10.3" ] eghcup set ${GHC_VERSION} [ "$(ghc --numeric-version)" = "${ghc_ver}" ] From 700e04535a5db0885d0745bea375346b44692971 Mon Sep 17 00:00:00 2001 From: Julian Ospald Date: Wed, 9 Jun 2021 19:03:48 +0200 Subject: [PATCH 08/12] Enable Mac AARCH64 --- .gitlab-ci.yml | 14 ++++---- .gitlab/before_script/darwin/install_deps.sh | 34 ++++++++++++++++---- 2 files changed, 35 insertions(+), 13 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 3482f01..26180ab 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -271,13 +271,13 @@ test:mac:latest: CABAL_VERSION: "3.4.0.0" needs: [] -# test:mac:recommended:aarch64: - # stage: test - # extends: .test_ghcup_version:darwin:aarch64 - # variables: - # GHC_VERSION: "8.10.5" - # CABAL_VERSION: "3.4.0.0" - # needs: [] +test:mac:recommended:aarch64: + stage: test + extends: .test_ghcup_version:darwin:aarch64 + variables: + GHC_VERSION: "8.10.5" + CABAL_VERSION: "3.4.0.0" + needs: [] ######## freebsd test ######## diff --git a/.gitlab/before_script/darwin/install_deps.sh b/.gitlab/before_script/darwin/install_deps.sh index 50e57d6..92ffdda 100755 --- a/.gitlab/before_script/darwin/install_deps.sh +++ b/.gitlab/before_script/darwin/install_deps.sh @@ -6,12 +6,34 @@ set -eux mkdir -p "${TMPDIR}" -curl -sSfL https://downloads.haskell.org/~ghcup/x86_64-apple-darwin-ghcup > ./ghcup-bin -chmod +x ghcup-bin +if [ $ARCH = 'ARM64' ] ; then + curl -O https://downloads.haskell.org/~ghc/8.10.5/ghc-8.10.5-aarch64-apple-darwin.tar.xz + tar -xf ghc-*.tar.* + cd ghc-* + ./configure --prefix="${GHCUP_INSTALL_BASE_PREFIX}"/.ghcup/ghc/8.10.5 + make install + for i in "${GHCUP_INSTALL_BASE_PREFIX}"/.ghcup/ghc/8.10.5/bin/*-8.10.5 ; do + ln -s "${i}" "${GHCUP_INSTALL_BASE_PREFIX}"/.ghcup/bin/${i##*/} + done + for x in "${GHCUP_INSTALL_BASE_PREFIX}"/.ghcup/bin/*-8.10.5 ; do + ln -s ${x##*/} ${x%-8.10.5} + done + unset x i + cd .. + rm -rf ghc-8.10.5 ghc-*.tar.* -./ghcup-bin upgrade -i -f -./ghcup-bin install ${GHC_VERSION} -./ghcup-bin set ${GHC_VERSION} -./ghcup-bin install-cabal ${CABAL_VERSION} + curl -O https://github.com/haskell/cabal/files/6617482/cabal-install-3.5-arm64-darwin-11.4-bootstrapped.tar.gz + tar -xf cabal-install-* + mv cabal "${GHCUP_INSTALL_BASE_PREFIX}"/.ghcup/bin/cabal + rm -rf cabal-install +else + curl -sSfL https://downloads.haskell.org/~ghcup/x86_64-apple-darwin-ghcup > ./ghcup-bin + chmod +x ghcup-bin + + ./ghcup-bin upgrade -i -f + ./ghcup-bin install ${GHC_VERSION} + ./ghcup-bin set ${GHC_VERSION} + ./ghcup-bin install-cabal ${CABAL_VERSION} +fi exit 0 From 5214c35b206935313a43dca8579216f8559ed7ba Mon Sep 17 00:00:00 2001 From: Julian Ospald Date: Wed, 9 Jun 2021 19:45:23 +0200 Subject: [PATCH 09/12] Fix CI --- .gitlab-ci.yml | 27 +++++++++++++++++++++------ .gitlab/script/ghcup_version.sh | 21 ++++++++++++--------- 2 files changed, 33 insertions(+), 15 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 26180ab..422755c 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -239,7 +239,7 @@ test:linux:recommended:armv7: stage: test extends: .test_ghcup_version:armv7 variables: - GHC_VERSION: "8.10.5" + GHC_VERSION: "8.10.4" CABAL_VERSION: "3.4.0.0" when: manual needs: [] @@ -248,7 +248,7 @@ test:linux:recommended:aarch64: stage: test extends: .test_ghcup_version:aarch64 variables: - GHC_VERSION: "8.10.5" + GHC_VERSION: "8.10.4" CABAL_VERSION: "3.4.0.0" when: manual needs: [] @@ -259,7 +259,7 @@ test:mac:recommended: stage: test extends: .test_ghcup_version:darwin variables: - GHC_VERSION: "8.10.5" + GHC_VERSION: "8.10.4" CABAL_VERSION: "3.4.0.0" needs: [] @@ -286,7 +286,7 @@ test:freebsd:recommended: stage: test extends: .test_ghcup_version:freebsd variables: - GHC_VERSION: "8.10.5" + GHC_VERSION: "8.10.4" CABAL_VERSION: "3.4.0.0" allow_failure: true # freebsd runners are unreliable when: manual @@ -341,7 +341,7 @@ release:linux:armv7: - ./.gitlab/before_script/linux/install_deps_manual.sh variables: ARTIFACT: "armv7-linux-ghcup" - GHC_VERSION: "8.10.5" + GHC_VERSION: "8.10.4" CABAL_VERSION: "3.4.0.0" release:linux:aarch64: @@ -354,7 +354,7 @@ release:linux:aarch64: - ./.gitlab/before_script/linux/install_deps_manual.sh variables: ARTIFACT: "aarch64-linux-ghcup" - GHC_VERSION: "8.10.5" + GHC_VERSION: "8.10.4" CABAL_VERSION: "3.4.0.0" ######## darwin release ######## @@ -374,6 +374,21 @@ release:darwin: CABAL_VERSION: "3.4.0.0" MACOSX_DEPLOYMENT_TARGET: "10.7" +release:darwin:aarch64: + stage: release + needs: ["test:mac:recommended:aarch64"] + extends: + - .darwin:aarch64 + - .release_ghcup + - .root_cleanup + before_script: + - ./.gitlab/before_script/darwin/install_deps.sh + variables: + ARTIFACT: "aarch64-apple-darwin-ghcup" + GHC_VERSION: "8.10.5" + CABAL_VERSION: "3.4.0.0" + MACOSX_DEPLOYMENT_TARGET: "10.7" + ######## freebsd release ######## diff --git a/.gitlab/script/ghcup_version.sh b/.gitlab/script/ghcup_version.sh index a3d57b7..05823a6 100755 --- a/.gitlab/script/ghcup_version.sh +++ b/.gitlab/script/ghcup_version.sh @@ -60,15 +60,16 @@ else fi -cp "$(ecabal new-exec -w ghc-${GHC_VERSION} --verbose=0 --offline sh -- -c 'command -v ghcup')" . -cp "$(ecabal new-exec -w ghc-${GHC_VERSION} --verbose=0 --offline sh -- -c 'command -v ghcup-gen')" . - -cp ./ghcup "$CI_PROJECT_DIR"/.local/bin/ghcup -cp ./ghcup-gen "$CI_PROJECT_DIR"/.local/bin/ghcup-gen +cp "$(ecabal new-exec -w ghc-${GHC_VERSION} --verbose=0 --offline sh -- -c 'command -v ghcup')" "$CI_PROJECT_DIR"/.local/bin/ghcup +cp "$(ecabal new-exec -w ghc-${GHC_VERSION} --verbose=0 --offline sh -- -c 'command -v ghcup-gen')" "$CI_PROJECT_DIR"/.local/bin/ghcup-gen ### cleanup -rm -rf "${GHCUP_INSTALL_BASE_PREFIX}"/.ghcup +if [ "${OS}" = "WINDOWS" ] ; then + rm -rf "${GHCUP_INSTALL_BASE_PREFIX}"/ghcup +else + rm -rf "${GHCUP_INSTALL_BASE_PREFIX}"/.ghcup +fi ### manual cli based testing @@ -92,9 +93,11 @@ eghcup list -t cabal ghc_ver=$(ghc --numeric-version) ghc --version -ghci --version -ghc-$(ghc --numeric-version) --version -ghci-$(ghc --numeric-version) --version +ghc-${ghc_ver} --version +if [ "${OS}" != "WINDOWS" ] ; then + ghci --version + ghci-${ghc_ver} --version +fi # test installing new ghc doesn't mess with currently set GHC From 924bc8698d9b768f19457801f1dcbba9daacc35d Mon Sep 17 00:00:00 2001 From: Julian Ospald Date: Thu, 10 Jun 2021 10:58:07 +0200 Subject: [PATCH 10/12] Make Silent a switch --- bootstrap-haskell.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bootstrap-haskell.ps1 b/bootstrap-haskell.ps1 index 3cd1a9a..cf1296c 100644 --- a/bootstrap-haskell.ps1 +++ b/bootstrap-haskell.ps1 @@ -14,7 +14,7 @@ #> param ( # Run a non-interactive installation - [bool]$Silent = $false, + [switch]$Silent, # Specify the install root (default: 'C:\') [string]$InstallDir, # Instead of installing a new MSys2, use an existing installation From e742be769397d9198f71d9fda314b7821acd8f16 Mon Sep 17 00:00:00 2001 From: Julian Ospald Date: Thu, 10 Jun 2021 10:58:24 +0200 Subject: [PATCH 11/12] Allow to specify cabal directory --- bootstrap-haskell.ps1 | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/bootstrap-haskell.ps1 b/bootstrap-haskell.ps1 index cf1296c..ea15f3e 100644 --- a/bootstrap-haskell.ps1 +++ b/bootstrap-haskell.ps1 @@ -19,6 +19,8 @@ param ( [string]$InstallDir, # Instead of installing a new MSys2, use an existing installation [string]$ExistingMsys2Dir, + # Specify the cabal root directory (default: '$InstallDir\cabal') + [string]$CabalDir, # Perform a quick installation, omitting some expensive operations (you may have to install dependencies yourself later) [bool]$Quick, # Overwrite (or rather backup) a previous install @@ -323,6 +325,39 @@ Create-Shortcut -SourceExe 'https://www.msys2.org/docs/package-management' -Argu Print-Msg -msg ('Adding {0}\bin to Users Path...' -f $GhcupDir) Add-EnvPath -Path ('{0}\bin' -f ([System.IO.Path]::GetFullPath("$GhcupDir"))) -Container 'User' +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). Press enter to accept the default [{0}]:' -f $defaultCabalDir) + $CabalDirPrompt = Read-Host + $CabDirEnv = ($defaultCabalDir,$CabalDirPrompt)[[bool]$CabalDirPrompt] + + 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) +} + +$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) @@ -334,9 +369,9 @@ if ($Silent) { } if ((Get-Process -ID $PID).ProcessName.StartsWith("bootstrap-haskell")) { - Exec "$Bash" '-lc' ('{4} [ -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 ; curl --proto ''=https'' --tlsv1.2 -sSf {0} | bash' -f $BootstrapUrl, $MsysDir, $GhcupBasePrefix, $GhcupDir, $SilentExport) + Exec "$Bash" '-lc' ('{4} [ -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}'' ; curl --proto ''=https'' --tlsv1.2 -sSf {0} | bash' -f $BootstrapUrl, $MsysDir, $GhcupBasePrefix, $GhcupDir, $SilentExport, $CabalDirFull) } else { - Exec "$Msys2Shell" '-mingw64' '-mintty' '-c' ('{4} [ -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 ; trap ''echo Press any key to exit && read -n 1 && exit'' 2 ; curl --proto =https --tlsv1.2 -sSf -k {0} | bash ; echo ''Press any key to exit'' && read -n 1' -f $BootstrapUrl, $MsysDir, $GhcupBasePrefix, $GhcupDir, $SilentExport) + Exec "$Msys2Shell" '-mingw64' '-mintty' '-c' ('{4} [ -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 ; curl --proto =https --tlsv1.2 -sSf -k {0} | bash ; echo ''Press any key to exit'' && read -n 1' -f $BootstrapUrl, $MsysDir, $GhcupBasePrefix, $GhcupDir, $SilentExport, $CabalDirFull) } From f7868dc646835f5f9d192d6f4a96a508ebc85097 Mon Sep 17 00:00:00 2001 From: Julian Ospald Date: Thu, 10 Jun 2021 13:57:02 +0200 Subject: [PATCH 12/12] Update install_deps --- .gitlab/before_script/darwin/install_deps.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitlab/before_script/darwin/install_deps.sh b/.gitlab/before_script/darwin/install_deps.sh index 92ffdda..cd7d1ac 100755 --- a/.gitlab/before_script/darwin/install_deps.sh +++ b/.gitlab/before_script/darwin/install_deps.sh @@ -7,7 +7,7 @@ set -eux mkdir -p "${TMPDIR}" if [ $ARCH = 'ARM64' ] ; then - curl -O https://downloads.haskell.org/~ghc/8.10.5/ghc-8.10.5-aarch64-apple-darwin.tar.xz + curl -L -O https://downloads.haskell.org/~ghc/8.10.5/ghc-8.10.5-aarch64-apple-darwin.tar.xz tar -xf ghc-*.tar.* cd ghc-* ./configure --prefix="${GHCUP_INSTALL_BASE_PREFIX}"/.ghcup/ghc/8.10.5 @@ -22,8 +22,8 @@ if [ $ARCH = 'ARM64' ] ; then cd .. rm -rf ghc-8.10.5 ghc-*.tar.* - curl -O https://github.com/haskell/cabal/files/6617482/cabal-install-3.5-arm64-darwin-11.4-bootstrapped.tar.gz - tar -xf cabal-install-* + curl -L -O https://github.com/haskell/cabal/files/6617482/cabal-install-3.5-arm64-darwin-11.4-bootstrapped.tar.gz + tar xf cabal-install-* mv cabal "${GHCUP_INSTALL_BASE_PREFIX}"/.ghcup/bin/cabal rm -rf cabal-install else