Compare commits
43 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
4064803e23
|
|||
|
2e03b075f8
|
|||
|
fe9c125bd6
|
|||
|
503fd57d7c
|
|||
|
e74e746213
|
|||
|
065f9c4965
|
|||
|
32f3c36589
|
|||
|
c2a8d39fb4
|
|||
|
f08cbe70fb
|
|||
|
a9630d0802
|
|||
|
c5c6c431b5
|
|||
|
71d78d2d72
|
|||
|
ccecda2eff
|
|||
|
3a5f8d6139
|
|||
|
74e0f39bc2
|
|||
|
274978a8a7
|
|||
|
8eea9bd6a5
|
|||
|
626a2dd020
|
|||
|
6b6ce221e0
|
|||
|
d038c361c0
|
|||
|
c05876cc60
|
|||
|
b9c4c9a0b7
|
|||
|
6697e804ee
|
|||
|
2c57def8f1
|
|||
|
62b16e957b
|
|||
|
18d7bdd85c
|
|||
|
190b5dedba
|
|||
|
886e45f788
|
|||
|
360daf2a09
|
|||
|
7bb67dd4c6
|
|||
|
72c4ea70c4
|
|||
|
0ae42dd71e
|
|||
|
1df1e7eb98
|
|||
|
9592021c48
|
|||
|
9a9c3b340e
|
|||
|
abd64cb3fa
|
|||
|
b366a50af1
|
|||
|
e4b9eeefc6
|
|||
|
4d7a8557eb
|
|||
|
c23357df81
|
|||
|
f728d5aa23
|
|||
|
ac59563adf
|
|||
|
b2d2996077
|
4
.github/workflows/release.yaml
vendored
4
.github/workflows/release.yaml
vendored
@@ -44,8 +44,8 @@ jobs:
|
|||||||
|
|
||||||
- uses: haskell/actions/setup@v1.2
|
- uses: haskell/actions/setup@v1.2
|
||||||
with:
|
with:
|
||||||
ghc-version: 8.10.4
|
ghc-version: 8.10.7
|
||||||
cabal-version: 3.4.0.0
|
cabal-version: 3.6.2.0
|
||||||
|
|
||||||
- name: create ~/.local/bin
|
- name: create ~/.local/bin
|
||||||
run: mkdir -p "$HOME/.local/bin"
|
run: mkdir -p "$HOME/.local/bin"
|
||||||
|
|||||||
@@ -175,7 +175,7 @@ variables:
|
|||||||
- .brew_cache
|
- .brew_cache
|
||||||
before_script:
|
before_script:
|
||||||
# Install brew locally in the project dir. Packages will also be installed here.
|
# Install brew locally in the project dir. Packages will also be installed here.
|
||||||
- git clone --depth=1 https://github.com/Homebrew/brew $CI_PROJECT_DIR/.brew
|
- '[ -e "$CI_PROJECT_DIR/.brew" ] || git clone --depth=1 https://github.com/Homebrew/brew $CI_PROJECT_DIR/.brew'
|
||||||
- export PATH="$CI_PROJECT_DIR/.brew/bin:$CI_PROJECT_DIR/.brew/sbin:$PATH"
|
- export PATH="$CI_PROJECT_DIR/.brew/bin:$CI_PROJECT_DIR/.brew/sbin:$PATH"
|
||||||
|
|
||||||
# otherwise we seem to get intel binaries
|
# otherwise we seem to get intel binaries
|
||||||
@@ -186,8 +186,8 @@ variables:
|
|||||||
- export HOMEBREW_CACHE=$CI_PROJECT_DIR/.brew_cache
|
- export HOMEBREW_CACHE=$CI_PROJECT_DIR/.brew_cache
|
||||||
- mkdir -p $CI_PROJECT_DIR/.brew_logs
|
- mkdir -p $CI_PROJECT_DIR/.brew_logs
|
||||||
- export HOMEBREW_LOGS=$CI_PROJECT_DIR/.brew_logs
|
- export HOMEBREW_LOGS=$CI_PROJECT_DIR/.brew_logs
|
||||||
- mkdir -p $CI_PROJECT_DIR/.brew_tmp
|
- mkdir -p /private/tmp/.brew_tmp
|
||||||
- export HOMEBREW_TEMP=$CI_PROJECT_DIR/.brew_tmp
|
- export HOMEBREW_TEMP=/private/tmp/.brew_tmp
|
||||||
|
|
||||||
# update and install packages
|
# update and install packages
|
||||||
- brew update
|
- brew update
|
||||||
@@ -406,6 +406,7 @@ test:mac:aarch64:
|
|||||||
CABAL_VERSION: "3.6.2.0"
|
CABAL_VERSION: "3.6.2.0"
|
||||||
needs: []
|
needs: []
|
||||||
allow_failure: true
|
allow_failure: true
|
||||||
|
when: manual
|
||||||
|
|
||||||
|
|
||||||
######## freebsd test ########
|
######## freebsd test ########
|
||||||
@@ -533,7 +534,7 @@ release:darwin:aarch64:
|
|||||||
- .brew_cache
|
- .brew_cache
|
||||||
before_script:
|
before_script:
|
||||||
# Install brew locally in the project dir. Packages will also be installed here.
|
# Install brew locally in the project dir. Packages will also be installed here.
|
||||||
- git clone --depth=1 https://github.com/Homebrew/brew $CI_PROJECT_DIR/.brew
|
- '[ -e "$CI_PROJECT_DIR/.brew" ] || git clone --depth=1 https://github.com/Homebrew/brew $CI_PROJECT_DIR/.brew'
|
||||||
- export PATH="$CI_PROJECT_DIR/.brew/bin:$CI_PROJECT_DIR/.brew/sbin:$PATH"
|
- export PATH="$CI_PROJECT_DIR/.brew/bin:$CI_PROJECT_DIR/.brew/sbin:$PATH"
|
||||||
|
|
||||||
# otherwise we seem to get intel binaries
|
# otherwise we seem to get intel binaries
|
||||||
@@ -544,8 +545,8 @@ release:darwin:aarch64:
|
|||||||
- export HOMEBREW_CACHE=$CI_PROJECT_DIR/.brew_cache
|
- export HOMEBREW_CACHE=$CI_PROJECT_DIR/.brew_cache
|
||||||
- mkdir -p $CI_PROJECT_DIR/.brew_logs
|
- mkdir -p $CI_PROJECT_DIR/.brew_logs
|
||||||
- export HOMEBREW_LOGS=$CI_PROJECT_DIR/.brew_logs
|
- export HOMEBREW_LOGS=$CI_PROJECT_DIR/.brew_logs
|
||||||
- mkdir -p $CI_PROJECT_DIR/.brew_tmp
|
- mkdir -p /private/tmp/.brew_tmp
|
||||||
- export HOMEBREW_TEMP=$CI_PROJECT_DIR/.brew_tmp
|
- export HOMEBREW_TEMP=/private/tmp/.brew_tmp
|
||||||
|
|
||||||
# update and install packages
|
# update and install packages
|
||||||
- brew update
|
- brew update
|
||||||
@@ -566,6 +567,7 @@ release:darwin:aarch64:
|
|||||||
CABAL_VERSION: "3.6.2.0"
|
CABAL_VERSION: "3.6.2.0"
|
||||||
MACOSX_DEPLOYMENT_TARGET: "10.7"
|
MACOSX_DEPLOYMENT_TARGET: "10.7"
|
||||||
allow_failure: true
|
allow_failure: true
|
||||||
|
when: manual
|
||||||
|
|
||||||
|
|
||||||
######## freebsd release ########
|
######## freebsd release ########
|
||||||
|
|||||||
@@ -12,4 +12,8 @@ if [ "${OS}" = "WINDOWS" ] ; then
|
|||||||
rm -Rf /c/ghcup
|
rm -Rf /c/ghcup
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [ "${OS}" = "DARWIN" ] ; then
|
||||||
|
rm -Rf /private/tmp/.brew_tmp
|
||||||
|
fi
|
||||||
|
|
||||||
exit 0
|
exit 0
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ cabal --version
|
|||||||
|
|
||||||
eghcup debug-info
|
eghcup debug-info
|
||||||
|
|
||||||
eghcup compile hls -j $(nproc) -v ${HLS_TARGET_VERSION} ${GHC_VERSION}
|
eghcup compile hls -j $(nproc) -v ${HLS_TARGET_VERSION} --ghc ${GHC_VERSION}
|
||||||
|
|
||||||
[ `$(eghcup whereis hls ${HLS_TARGET_VERSION}) --numeric-version` = "${HLS_TARGET_VERSION}" ] || [ `$(eghcup whereis hls ${HLS_TARGET_VERSION}) --numeric-version | sed 's/.0$//'` = "${HLS_TARGET_VERSION}" ]
|
[ `$(eghcup whereis hls ${HLS_TARGET_VERSION}) --numeric-version` = "${HLS_TARGET_VERSION}" ] || [ `$(eghcup whereis hls ${HLS_TARGET_VERSION}) --numeric-version | sed 's/.0$//'` = "${HLS_TARGET_VERSION}" ]
|
||||||
|
|
||||||
|
|||||||
@@ -85,7 +85,6 @@ else
|
|||||||
ext=''
|
ext=''
|
||||||
fi
|
fi
|
||||||
cp "$(ecabal new-exec -w ghc-${GHC_VERSION} --verbose=0 --offline sh -- -c 'command -v ghcup')" "$CI_PROJECT_DIR"/.local/bin/ghcup${ext}
|
cp "$(ecabal new-exec -w ghc-${GHC_VERSION} --verbose=0 --offline sh -- -c 'command -v ghcup')" "$CI_PROJECT_DIR"/.local/bin/ghcup${ext}
|
||||||
cp "$(ecabal new-exec -w ghc-${GHC_VERSION} --verbose=0 --offline sh -- -c 'command -v ghcup-gen')" "$CI_PROJECT_DIR"/.local/bin/ghcup-gen${ext}
|
|
||||||
|
|
||||||
### cleanup
|
### cleanup
|
||||||
|
|
||||||
@@ -94,8 +93,6 @@ rm -rf "${GHCUP_DIR}"
|
|||||||
### manual cli based testing
|
### manual cli based testing
|
||||||
|
|
||||||
|
|
||||||
ghcup-gen check -f data/metadata/ghcup-${JSON_VERSION}.yaml
|
|
||||||
|
|
||||||
eghcup --numeric-version
|
eghcup --numeric-version
|
||||||
|
|
||||||
eghcup install ghc ${GHC_VERSION}
|
eghcup install ghc ${GHC_VERSION}
|
||||||
|
|||||||
15
CHANGELOG.md
15
CHANGELOG.md
@@ -1,5 +1,20 @@
|
|||||||
# Revision history for ghcup
|
# Revision history for ghcup
|
||||||
|
|
||||||
|
## 0.1.17.4 -- 2021-11-13
|
||||||
|
|
||||||
|
* add `--metadata-caching` option, allowing to also disable yaml metadata caching wrt [#278](https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/278)
|
||||||
|
* make upgrading ghcup in TUI more pleasant wrt [#276](https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/276)
|
||||||
|
* fix parsing of atypical GHC versions (e.g. `8.10.5-patch1`)
|
||||||
|
* fix compiling HLS dynamically linked, also see [#245](https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/245)
|
||||||
|
* redo (and break) some of the `ghcup compile <tool>` interface, improving patch options and setting custom cabal.project files
|
||||||
|
|
||||||
|
## 0.1.17.3 -- 2021-10-27
|
||||||
|
|
||||||
|
* clean up during unpack failures as well
|
||||||
|
* migrate te aeson-2.0.1.0
|
||||||
|
* switch to yaml-streamly to fix performance regression wrt [#270](https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/270)
|
||||||
|
* use [github.com/haskell/ghcup-metadata](https://github.com/haskell/ghcup-metadata) for metadata file download (better caching)
|
||||||
|
|
||||||
## 0.1.17.2 -- 2021-09-30
|
## 0.1.17.2 -- 2021-09-30
|
||||||
|
|
||||||
* Honour GHC bootstrap compiler during git clone stages wrt [#250](https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/250)
|
* Honour GHC bootstrap compiler during git clone stages wrt [#250](https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/250)
|
||||||
|
|||||||
@@ -9,3 +9,5 @@
|
|||||||
GHCup is an installer for the general purpose language [Haskell](https://www.haskell.org/).
|
GHCup is an installer for the general purpose language [Haskell](https://www.haskell.org/).
|
||||||
|
|
||||||
Visit the [documentation](https://www.haskell.org/ghcup/) for installation instructions.
|
Visit the [documentation](https://www.haskell.org/ghcup/) for installation instructions.
|
||||||
|
|
||||||
|
If you're looking for the metadata YAML files, see here: [https://github.com/haskell/ghcup-metadata](https://github.com/haskell/ghcup-metadata)
|
||||||
|
|||||||
@@ -1,155 +0,0 @@
|
|||||||
{-# LANGUAGE CPP #-}
|
|
||||||
{-# LANGUAGE DataKinds #-}
|
|
||||||
{-# LANGUAGE DuplicateRecordFields #-}
|
|
||||||
{-# LANGUAGE OverloadedStrings #-}
|
|
||||||
{-# LANGUAGE TypeApplications #-}
|
|
||||||
|
|
||||||
|
|
||||||
module Main where
|
|
||||||
|
|
||||||
import GHCup.Types
|
|
||||||
import GHCup.Errors
|
|
||||||
import GHCup.Platform
|
|
||||||
import GHCup.Utils.Dirs
|
|
||||||
import GHCup.Utils.Logger
|
|
||||||
import GHCup.Types.JSON ( )
|
|
||||||
|
|
||||||
import Control.Exception ( displayException )
|
|
||||||
import Control.Monad.Trans.Reader ( runReaderT )
|
|
||||||
import Control.Monad.IO.Class
|
|
||||||
import Data.Char ( toLower )
|
|
||||||
import Data.Maybe
|
|
||||||
#if !MIN_VERSION_base(4,13,0)
|
|
||||||
import Data.Semigroup ( (<>) )
|
|
||||||
#endif
|
|
||||||
import Options.Applicative hiding ( style )
|
|
||||||
import Haskus.Utils.Variant.Excepts
|
|
||||||
import System.Console.Pretty
|
|
||||||
import System.Environment
|
|
||||||
import System.Exit
|
|
||||||
import System.IO ( stderr )
|
|
||||||
import Text.Regex.Posix
|
|
||||||
import Validate
|
|
||||||
import Text.PrettyPrint.HughesPJClass ( prettyShow )
|
|
||||||
|
|
||||||
import qualified Data.Text.IO as T
|
|
||||||
import qualified Data.Text as T
|
|
||||||
import qualified Data.ByteString as B
|
|
||||||
import qualified Data.Yaml.Aeson as Y
|
|
||||||
|
|
||||||
|
|
||||||
data Options = Options
|
|
||||||
{ optCommand :: Command
|
|
||||||
}
|
|
||||||
|
|
||||||
data Command = ValidateYAML ValidateYAMLOpts
|
|
||||||
| ValidateTarballs ValidateYAMLOpts TarballFilter
|
|
||||||
|
|
||||||
|
|
||||||
data Input
|
|
||||||
= FileInput FilePath -- optsparse-applicative doesn't handle ByteString correctly anyway
|
|
||||||
| StdInput
|
|
||||||
|
|
||||||
fileInput :: Parser Input
|
|
||||||
fileInput =
|
|
||||||
FileInput
|
|
||||||
<$> strOption
|
|
||||||
(long "file" <> short 'f' <> metavar "FILENAME" <> help
|
|
||||||
"Input file to validate"
|
|
||||||
)
|
|
||||||
|
|
||||||
stdInput :: Parser Input
|
|
||||||
stdInput = flag'
|
|
||||||
StdInput
|
|
||||||
(short 'i' <> long "stdin" <> help "Validate from stdin (default)")
|
|
||||||
|
|
||||||
inputP :: Parser Input
|
|
||||||
inputP = fileInput <|> stdInput
|
|
||||||
|
|
||||||
data ValidateYAMLOpts = ValidateYAMLOpts
|
|
||||||
{ vInput :: Maybe Input
|
|
||||||
}
|
|
||||||
|
|
||||||
validateYAMLOpts :: Parser ValidateYAMLOpts
|
|
||||||
validateYAMLOpts = ValidateYAMLOpts <$> optional inputP
|
|
||||||
|
|
||||||
tarballFilterP :: Parser TarballFilter
|
|
||||||
tarballFilterP = option readm $
|
|
||||||
long "tarball-filter" <> short 'u' <> metavar "<tool>-<version>" <> value def
|
|
||||||
<> help "Only check certain tarballs (format: <tool>-<version>)"
|
|
||||||
where
|
|
||||||
def = TarballFilter (Right Nothing) (makeRegex ("" :: String))
|
|
||||||
readm = do
|
|
||||||
s <- str
|
|
||||||
case span (/= '-') s of
|
|
||||||
(_, []) -> fail "invalid format, missing '-' after the tool name"
|
|
||||||
(t, v) | [tool] <- [ tool | tool <- [minBound..maxBound], low (show tool) == low t ] ->
|
|
||||||
pure (TarballFilter $ Right $ Just tool) <*> makeRegexOptsM compIgnoreCase execBlank (drop 1 v)
|
|
||||||
(t, v) | [tool] <- [ tool | tool <- [minBound..maxBound], low (show tool) == low t ] ->
|
|
||||||
pure (TarballFilter $ Left tool) <*> makeRegexOptsM compIgnoreCase execBlank (drop 1 v)
|
|
||||||
_ -> fail "invalid tool"
|
|
||||||
low = fmap toLower
|
|
||||||
|
|
||||||
|
|
||||||
opts :: Parser Options
|
|
||||||
opts = Options <$> com
|
|
||||||
|
|
||||||
com :: Parser Command
|
|
||||||
com = subparser
|
|
||||||
( command
|
|
||||||
"check"
|
|
||||||
( ValidateYAML
|
|
||||||
<$> info (validateYAMLOpts <**> helper)
|
|
||||||
(progDesc "Validate the YAML")
|
|
||||||
)
|
|
||||||
<> command
|
|
||||||
"check-tarballs"
|
|
||||||
(info
|
|
||||||
((ValidateTarballs <$> validateYAMLOpts <*> tarballFilterP) <**> helper)
|
|
||||||
(progDesc "Validate all tarballs (download and checksum)")
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
main :: IO ()
|
|
||||||
main = do
|
|
||||||
no_color <- isJust <$> lookupEnv "NO_COLOR"
|
|
||||||
let loggerConfig = LoggerConfig { lcPrintDebug = True
|
|
||||||
, consoleOutter = T.hPutStr stderr
|
|
||||||
, fileOutter = \_ -> pure ()
|
|
||||||
, fancyColors = not no_color
|
|
||||||
}
|
|
||||||
dirs <- liftIO getAllDirs
|
|
||||||
let leanAppstate = LeanAppState (Settings True False Never Curl True GHCupURL False GPGNone False) dirs defaultKeyBindings loggerConfig
|
|
||||||
|
|
||||||
pfreq <- (
|
|
||||||
flip runReaderT leanAppstate . runE @'[NoCompatiblePlatform, NoCompatibleArch, DistroNotFound] $ platformRequest
|
|
||||||
) >>= \case
|
|
||||||
VRight r -> pure r
|
|
||||||
VLeft e -> do
|
|
||||||
flip runReaderT leanAppstate $ logError $ T.pack $ prettyShow e
|
|
||||||
liftIO $ exitWith (ExitFailure 2)
|
|
||||||
|
|
||||||
let appstate = AppState (Settings True False Never Curl True GHCupURL False GPGNone False) dirs defaultKeyBindings (GHCupInfo mempty mempty mempty) pfreq loggerConfig
|
|
||||||
|
|
||||||
_ <- customExecParser (prefs showHelpOnError) (info (opts <**> helper) idm)
|
|
||||||
>>= \Options {..} -> case optCommand of
|
|
||||||
ValidateYAML vopts -> withValidateYamlOpts vopts (\dl m -> flip runReaderT appstate $ validate dl m)
|
|
||||||
ValidateTarballs vopts tarballFilter -> withValidateYamlOpts vopts (\dl m -> flip runReaderT appstate $ validateTarballs tarballFilter dl m)
|
|
||||||
pure ()
|
|
||||||
|
|
||||||
where
|
|
||||||
withValidateYamlOpts vopts f = case vopts of
|
|
||||||
ValidateYAMLOpts { vInput = Nothing } ->
|
|
||||||
B.getContents >>= valAndExit f
|
|
||||||
ValidateYAMLOpts { vInput = Just StdInput } ->
|
|
||||||
B.getContents >>= valAndExit f
|
|
||||||
ValidateYAMLOpts { vInput = Just (FileInput file) } ->
|
|
||||||
B.readFile file >>= valAndExit f
|
|
||||||
valAndExit f contents = do
|
|
||||||
(GHCupInfo _ av gt) <- case Y.decodeEither' contents of
|
|
||||||
Right r -> pure r
|
|
||||||
Left e -> die (color Red $ displayException e)
|
|
||||||
f av gt
|
|
||||||
>>= exitWith
|
|
||||||
@@ -1,280 +0,0 @@
|
|||||||
{-# LANGUAGE CPP #-}
|
|
||||||
{-# LANGUAGE DataKinds #-}
|
|
||||||
{-# LANGUAGE FlexibleContexts #-}
|
|
||||||
{-# LANGUAGE QuasiQuotes #-}
|
|
||||||
{-# LANGUAGE TemplateHaskell #-}
|
|
||||||
{-# LANGUAGE TypeApplications #-}
|
|
||||||
{-# LANGUAGE ViewPatterns #-}
|
|
||||||
{-# LANGUAGE OverloadedStrings #-}
|
|
||||||
|
|
||||||
module Validate where
|
|
||||||
|
|
||||||
import GHCup
|
|
||||||
import GHCup.Download
|
|
||||||
import GHCup.Errors
|
|
||||||
import GHCup.Types
|
|
||||||
import GHCup.Types.Optics
|
|
||||||
import GHCup.Utils
|
|
||||||
import GHCup.Utils.Logger
|
|
||||||
import GHCup.Utils.Version.QQ
|
|
||||||
|
|
||||||
import Codec.Archive
|
|
||||||
import Control.Applicative
|
|
||||||
import Control.Exception.Safe
|
|
||||||
import Control.Monad
|
|
||||||
import Control.Monad.IO.Class
|
|
||||||
import Control.Monad.Reader.Class
|
|
||||||
import Control.Monad.Trans.Class ( lift )
|
|
||||||
import Control.Monad.Trans.Reader ( runReaderT )
|
|
||||||
import Control.Monad.Trans.Resource ( runResourceT
|
|
||||||
, MonadUnliftIO
|
|
||||||
)
|
|
||||||
import Data.Containers.ListUtils ( nubOrd )
|
|
||||||
import Data.IORef
|
|
||||||
import Data.List
|
|
||||||
import Data.Versions
|
|
||||||
import Haskus.Utils.Variant.Excepts
|
|
||||||
import Optics
|
|
||||||
import System.FilePath
|
|
||||||
import System.Exit
|
|
||||||
import Text.ParserCombinators.ReadP
|
|
||||||
import Text.PrettyPrint.HughesPJClass ( prettyShow )
|
|
||||||
import Text.Regex.Posix
|
|
||||||
|
|
||||||
import qualified Data.Map.Strict as M
|
|
||||||
import qualified Data.Text as T
|
|
||||||
import qualified Data.Version as V
|
|
||||||
|
|
||||||
|
|
||||||
data ValidationError = InternalError String
|
|
||||||
deriving Show
|
|
||||||
|
|
||||||
instance Exception ValidationError
|
|
||||||
|
|
||||||
|
|
||||||
addError :: (MonadReader (IORef Int) m, MonadIO m, Monad m) => m ()
|
|
||||||
addError = do
|
|
||||||
ref <- ask
|
|
||||||
liftIO $ modifyIORef ref (+ 1)
|
|
||||||
|
|
||||||
|
|
||||||
validate :: (Monad m, MonadReader env m, HasLog env, MonadThrow m, MonadIO m, MonadUnliftIO m)
|
|
||||||
=> GHCupDownloads
|
|
||||||
-> M.Map GlobalTool DownloadInfo
|
|
||||||
-> m ExitCode
|
|
||||||
validate dls _ = do
|
|
||||||
ref <- liftIO $ newIORef 0
|
|
||||||
|
|
||||||
-- verify binary downloads --
|
|
||||||
flip runReaderT ref $ do
|
|
||||||
-- unique tags
|
|
||||||
forM_ (M.toList dls) $ \(t, _) -> checkUniqueTags t
|
|
||||||
|
|
||||||
-- required platforms
|
|
||||||
forM_ (M.toList dls) $ \(t, versions) ->
|
|
||||||
forM_ (M.toList versions) $ \(v, vi) ->
|
|
||||||
forM_ (M.toList $ _viArch vi) $ \(arch, pspecs) -> do
|
|
||||||
checkHasRequiredPlatforms t v (_viTags vi) arch (M.keys pspecs)
|
|
||||||
|
|
||||||
checkGHCVerIsValid
|
|
||||||
forM_ (M.toList dls) $ \(t, _) -> checkMandatoryTags t
|
|
||||||
_ <- checkGHCHasBaseVersion
|
|
||||||
|
|
||||||
-- exit
|
|
||||||
e <- liftIO $ readIORef ref
|
|
||||||
if e > 0
|
|
||||||
then pure $ ExitFailure e
|
|
||||||
else do
|
|
||||||
lift $ logInfo "All good"
|
|
||||||
pure ExitSuccess
|
|
||||||
where
|
|
||||||
checkHasRequiredPlatforms t v tags arch pspecs = do
|
|
||||||
let v' = prettyVer v
|
|
||||||
arch' = prettyShow arch
|
|
||||||
when (Linux UnknownLinux `notElem` pspecs) $ do
|
|
||||||
lift $ logError $
|
|
||||||
"Linux UnknownLinux missing for for " <> T.pack (prettyShow t) <> " " <> v' <> " " <> T.pack arch'
|
|
||||||
addError
|
|
||||||
when ((Darwin `notElem` pspecs) && arch == A_64) $ do
|
|
||||||
lift $ logError $ "Darwin missing for for " <> T.pack (prettyShow t) <> " " <> v' <> " " <> T.pack arch'
|
|
||||||
addError
|
|
||||||
when ((FreeBSD `notElem` pspecs) && arch == A_64) $ lift $ logWarn $
|
|
||||||
"FreeBSD missing for for " <> T.pack (prettyShow t) <> " " <> v' <> " " <> T.pack arch'
|
|
||||||
when (Windows `notElem` pspecs && arch == A_64) $ do
|
|
||||||
lift $ logError $ "Windows missing for for " <> T.pack (prettyShow t) <> " " <> v' <> " " <> T.pack arch'
|
|
||||||
addError
|
|
||||||
|
|
||||||
-- alpine needs to be set explicitly, because
|
|
||||||
-- we cannot assume that "Linux UnknownLinux" runs on Alpine
|
|
||||||
-- (although it could be static)
|
|
||||||
when (Linux Alpine `notElem` pspecs) $
|
|
||||||
case t of
|
|
||||||
GHCup | arch `elem` [A_64, A_32] -> lift (logError $ "Linux Alpine missing for " <> T.pack (prettyShow t) <> " " <> v' <> " " <> T.pack (prettyShow arch)) >> addError
|
|
||||||
Cabal | v > [vver|2.4.1.0|]
|
|
||||||
, arch `elem` [A_64, A_32] -> lift (logError $ "Linux Alpine missing for " <> T.pack (prettyShow t) <> " " <> v' <> " " <> T.pack (prettyShow arch)) >> addError
|
|
||||||
GHC | Latest `elem` tags || Recommended `elem` tags
|
|
||||||
, arch `elem` [A_64, A_32] -> lift (logError $ "Linux Alpine missing for " <> T.pack (prettyShow t) <> " " <> v' <> " " <> T.pack (prettyShow arch))
|
|
||||||
_ -> lift $ logWarn $ "Linux Alpine missing for " <> T.pack (prettyShow t) <> " " <> v' <> " " <> T.pack (prettyShow arch)
|
|
||||||
|
|
||||||
checkUniqueTags tool = do
|
|
||||||
let allTags = _viTags =<< M.elems (availableToolVersions dls tool)
|
|
||||||
let nonUnique =
|
|
||||||
fmap fst
|
|
||||||
. filter (\(_, b) -> not b)
|
|
||||||
<$> ( mapM
|
|
||||||
(\case
|
|
||||||
[] -> throwM $ InternalError "empty inner list"
|
|
||||||
(t : ts) ->
|
|
||||||
pure $ (t, ) (not (isUniqueTag t) || null ts)
|
|
||||||
)
|
|
||||||
. group
|
|
||||||
. sort
|
|
||||||
$ allTags
|
|
||||||
)
|
|
||||||
case join nonUnique of
|
|
||||||
[] -> pure ()
|
|
||||||
xs -> do
|
|
||||||
lift $ logError $ "Tags not unique for " <> T.pack (prettyShow tool) <> ": " <> T.pack (prettyShow xs)
|
|
||||||
addError
|
|
||||||
where
|
|
||||||
isUniqueTag Latest = True
|
|
||||||
isUniqueTag Recommended = True
|
|
||||||
isUniqueTag Old = False
|
|
||||||
isUniqueTag Prerelease = False
|
|
||||||
isUniqueTag (Base _) = False
|
|
||||||
isUniqueTag (UnknownTag _) = False
|
|
||||||
|
|
||||||
checkGHCVerIsValid = do
|
|
||||||
let ghcVers = toListOf (ix GHC % to M.keys % folded) dls
|
|
||||||
forM_ ghcVers $ \v ->
|
|
||||||
case [ x | (x,"") <- readP_to_S V.parseVersion (T.unpack . prettyVer $ v) ] of
|
|
||||||
[_] -> pure ()
|
|
||||||
_ -> do
|
|
||||||
lift $ logError $ "GHC version " <> prettyVer v <> " is not valid"
|
|
||||||
addError
|
|
||||||
|
|
||||||
-- a tool must have at least one of each mandatory tags
|
|
||||||
checkMandatoryTags tool = do
|
|
||||||
let allTags = _viTags =<< M.elems (availableToolVersions dls tool)
|
|
||||||
forM_ [Latest, Recommended] $ \t -> case t `elem` allTags of
|
|
||||||
False -> do
|
|
||||||
lift $ logError $ "Tag " <> T.pack (prettyShow t) <> " missing from " <> T.pack (prettyShow tool)
|
|
||||||
addError
|
|
||||||
True -> pure ()
|
|
||||||
|
|
||||||
-- all GHC versions must have a base tag
|
|
||||||
checkGHCHasBaseVersion = do
|
|
||||||
let allTags = M.toList $ availableToolVersions dls GHC
|
|
||||||
forM allTags $ \(ver, _viTags -> tags) -> case any isBase tags of
|
|
||||||
False -> do
|
|
||||||
lift $ logError $ "Base tag missing from GHC ver " <> prettyVer ver
|
|
||||||
addError
|
|
||||||
True -> pure ()
|
|
||||||
|
|
||||||
isBase (Base _) = True
|
|
||||||
isBase _ = False
|
|
||||||
|
|
||||||
data TarballFilter = TarballFilter
|
|
||||||
{ tfTool :: Either GlobalTool (Maybe Tool)
|
|
||||||
, tfVersion :: Regex
|
|
||||||
}
|
|
||||||
|
|
||||||
validateTarballs :: ( Monad m
|
|
||||||
, MonadReader env m
|
|
||||||
, HasLog env
|
|
||||||
, HasDirs env
|
|
||||||
, HasSettings env
|
|
||||||
, MonadThrow m
|
|
||||||
, MonadIO m
|
|
||||||
, MonadUnliftIO m
|
|
||||||
, MonadMask m
|
|
||||||
, Alternative m
|
|
||||||
, MonadFail m
|
|
||||||
)
|
|
||||||
=> TarballFilter
|
|
||||||
-> GHCupDownloads
|
|
||||||
-> M.Map GlobalTool DownloadInfo
|
|
||||||
-> m ExitCode
|
|
||||||
validateTarballs (TarballFilter etool versionRegex) dls gt = do
|
|
||||||
ref <- liftIO $ newIORef 0
|
|
||||||
|
|
||||||
-- download/verify all tarballs
|
|
||||||
let dlis = either (const []) (\tool -> nubOrd $ dls ^.. each %& indices (maybe (const True) (==) tool) %> each %& indices (matchTest versionRegex . T.unpack . prettyVer) % (viSourceDL % _Just `summing` viArch % each % each % each)) etool
|
|
||||||
let gdlis = nubOrd $ gt ^.. each
|
|
||||||
let allDls = either (const gdlis) (const dlis) etool
|
|
||||||
when (null allDls) $ logError "no tarballs selected by filter" *> runReaderT addError ref
|
|
||||||
forM_ allDls (downloadAll ref)
|
|
||||||
|
|
||||||
-- exit
|
|
||||||
e <- liftIO $ readIORef ref
|
|
||||||
if e > 0
|
|
||||||
then pure $ ExitFailure e
|
|
||||||
else do
|
|
||||||
logInfo "All good"
|
|
||||||
pure ExitSuccess
|
|
||||||
|
|
||||||
where
|
|
||||||
downloadAll :: ( MonadUnliftIO m
|
|
||||||
, MonadIO m
|
|
||||||
, MonadReader env m
|
|
||||||
, HasLog env
|
|
||||||
, HasDirs env
|
|
||||||
, HasSettings env
|
|
||||||
, MonadCatch m
|
|
||||||
, MonadMask m
|
|
||||||
, MonadThrow m
|
|
||||||
)
|
|
||||||
=> IORef Int
|
|
||||||
-> DownloadInfo
|
|
||||||
-> m ()
|
|
||||||
downloadAll ref dli = do
|
|
||||||
r <- runResourceT
|
|
||||||
. runE @'[DigestError
|
|
||||||
, GPGError
|
|
||||||
, DownloadFailed
|
|
||||||
, UnknownArchive
|
|
||||||
, ArchiveResult
|
|
||||||
]
|
|
||||||
$ do
|
|
||||||
case etool of
|
|
||||||
Right (Just GHCup) -> do
|
|
||||||
tmpUnpack <- lift mkGhcupTmpDir
|
|
||||||
_ <- liftE $ download (_dlUri dli) Nothing (Just (_dlHash dli)) tmpUnpack Nothing False
|
|
||||||
pure Nothing
|
|
||||||
Right _ -> do
|
|
||||||
p <- liftE $ downloadCached dli Nothing
|
|
||||||
fmap (Just . head . splitDirectories . head)
|
|
||||||
. liftE
|
|
||||||
. getArchiveFiles
|
|
||||||
$ p
|
|
||||||
Left ShimGen -> do
|
|
||||||
tmpUnpack <- lift mkGhcupTmpDir
|
|
||||||
_ <- liftE $ download (_dlUri dli) Nothing (Just (_dlHash dli)) tmpUnpack Nothing False
|
|
||||||
pure Nothing
|
|
||||||
case r of
|
|
||||||
VRight (Just basePath) -> do
|
|
||||||
case _dlSubdir dli of
|
|
||||||
Just (RealDir prel) -> do
|
|
||||||
logInfo
|
|
||||||
$ " verifying subdir: " <> T.pack prel
|
|
||||||
when (basePath /= prel) $ do
|
|
||||||
logError $
|
|
||||||
"Subdir doesn't match: expected " <> T.pack prel <> ", got " <> T.pack basePath
|
|
||||||
runReaderT addError ref
|
|
||||||
Just (RegexDir regexString) -> do
|
|
||||||
logInfo $
|
|
||||||
"verifying subdir (regex): " <> T.pack regexString
|
|
||||||
let regex = makeRegexOpts
|
|
||||||
compIgnoreCase
|
|
||||||
execBlank
|
|
||||||
regexString
|
|
||||||
unless (match regex basePath) $ do
|
|
||||||
logError $
|
|
||||||
"Subdir doesn't match: expected regex " <> T.pack regexString <> ", got " <> T.pack basePath
|
|
||||||
runReaderT addError ref
|
|
||||||
Nothing -> pure ()
|
|
||||||
VRight Nothing -> pure ()
|
|
||||||
VLeft e -> do
|
|
||||||
logError $
|
|
||||||
"Could not download (or verify hash) of " <> T.pack (show dli) <> ", Error was: " <> T.pack (prettyShow e)
|
|
||||||
runReaderT addError ref
|
|
||||||
@@ -10,6 +10,7 @@ module BrickMain where
|
|||||||
import GHCup
|
import GHCup
|
||||||
import GHCup.Download
|
import GHCup.Download
|
||||||
import GHCup.Errors
|
import GHCup.Errors
|
||||||
|
import GHCup.Types.Optics ( getDirs )
|
||||||
import GHCup.Types hiding ( LeanAppState(..) )
|
import GHCup.Types hiding ( LeanAppState(..) )
|
||||||
import GHCup.Utils
|
import GHCup.Utils
|
||||||
import GHCup.Utils.Logger
|
import GHCup.Utils.Logger
|
||||||
@@ -26,6 +27,9 @@ import Brick.Widgets.List ( listSelectedFocusedAttr
|
|||||||
)
|
)
|
||||||
import Codec.Archive
|
import Codec.Archive
|
||||||
import Control.Exception.Safe
|
import Control.Exception.Safe
|
||||||
|
#if !MIN_VERSION_base(4,13,0)
|
||||||
|
import Control.Monad.Fail ( MonadFail )
|
||||||
|
#endif
|
||||||
import Control.Monad.Reader
|
import Control.Monad.Reader
|
||||||
import Control.Monad.Trans.Except
|
import Control.Monad.Trans.Except
|
||||||
import Control.Monad.Trans.Resource
|
import Control.Monad.Trans.Resource
|
||||||
@@ -40,6 +44,8 @@ import Data.Vector ( Vector
|
|||||||
import Data.Versions hiding ( str )
|
import Data.Versions hiding ( str )
|
||||||
import Haskus.Utils.Variant.Excepts
|
import Haskus.Utils.Variant.Excepts
|
||||||
import Prelude hiding ( appendFile )
|
import Prelude hiding ( appendFile )
|
||||||
|
import System.Directory ( canonicalizePath )
|
||||||
|
import System.FilePath
|
||||||
import System.Exit
|
import System.Exit
|
||||||
import System.IO.Unsafe
|
import System.IO.Unsafe
|
||||||
import Text.PrettyPrint.HughesPJClass ( prettyShow )
|
import Text.PrettyPrint.HughesPJClass ( prettyShow )
|
||||||
@@ -48,6 +54,8 @@ import URI.ByteString
|
|||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
import qualified Graphics.Vty as Vty
|
import qualified Graphics.Vty as Vty
|
||||||
import qualified Data.Vector as V
|
import qualified Data.Vector as V
|
||||||
|
import System.Environment (getExecutablePath)
|
||||||
|
import qualified System.Posix.Process as SPP
|
||||||
|
|
||||||
|
|
||||||
hiddenTools :: [Tool]
|
hiddenTools :: [Tool]
|
||||||
@@ -432,27 +440,42 @@ install' _ (_, ListResult {..}) = do
|
|||||||
]
|
]
|
||||||
|
|
||||||
run (do
|
run (do
|
||||||
|
ce <- liftIO $ fmap (either (const Nothing) Just) $
|
||||||
|
try @_ @SomeException $ getExecutablePath >>= canonicalizePath
|
||||||
|
dirs <- lift getDirs
|
||||||
case lTool of
|
case lTool of
|
||||||
GHC -> do
|
GHC -> do
|
||||||
let vi = getVersionInfo lVer GHC dls
|
let vi = getVersionInfo lVer GHC dls
|
||||||
liftE $ installGHCBin lVer Nothing False $> vi
|
liftE $ installGHCBin lVer Nothing False $> (vi, dirs, ce)
|
||||||
Cabal -> do
|
Cabal -> do
|
||||||
let vi = getVersionInfo lVer Cabal dls
|
let vi = getVersionInfo lVer Cabal dls
|
||||||
liftE $ installCabalBin lVer Nothing False $> vi
|
liftE $ installCabalBin lVer Nothing False $> (vi, dirs, ce)
|
||||||
GHCup -> do
|
GHCup -> do
|
||||||
let vi = snd <$> getLatest dls GHCup
|
let vi = snd <$> getLatest dls GHCup
|
||||||
liftE $ upgradeGHCup Nothing False $> vi
|
liftE $ upgradeGHCup Nothing False $> (vi, dirs, ce)
|
||||||
HLS -> do
|
HLS -> do
|
||||||
let vi = getVersionInfo lVer HLS dls
|
let vi = getVersionInfo lVer HLS dls
|
||||||
liftE $ installHLSBin lVer Nothing False $> vi
|
liftE $ installHLSBin lVer Nothing False $> (vi, dirs, ce)
|
||||||
Stack -> do
|
Stack -> do
|
||||||
let vi = getVersionInfo lVer Stack dls
|
let vi = getVersionInfo lVer Stack dls
|
||||||
liftE $ installStackBin lVer Nothing False $> vi
|
liftE $ installStackBin lVer Nothing False $> (vi, dirs, ce)
|
||||||
)
|
)
|
||||||
>>= \case
|
>>= \case
|
||||||
VRight vi -> do
|
VRight (vi, Dirs{..}, Just ce) -> do
|
||||||
forM_ (_viPostInstall =<< vi) $ \msg ->
|
forM_ (_viPostInstall =<< vi) $ \msg -> logInfo msg
|
||||||
logInfo msg
|
case lTool of
|
||||||
|
GHCup -> do
|
||||||
|
up <- liftIO $ fmap (either (const Nothing) Just)
|
||||||
|
$ try @_ @SomeException $ canonicalizePath (binDir </> "ghcup" <.> exeExt)
|
||||||
|
when ((normalise <$> up) == Just (normalise ce)) $
|
||||||
|
-- TODO: track cli arguments of previous invocation
|
||||||
|
liftIO $ SPP.executeFile ce False ["tui"] Nothing
|
||||||
|
logInfo "Please restart 'ghcup' for the changes to take effect"
|
||||||
|
_ -> pure ()
|
||||||
|
pure $ Right ()
|
||||||
|
VRight (vi, _, _) -> do
|
||||||
|
forM_ (_viPostInstall =<< vi) $ \msg -> logInfo msg
|
||||||
|
logInfo "Please restart 'ghcup' for the changes to take effect"
|
||||||
pure $ Right ()
|
pure $ Right ()
|
||||||
VLeft (V (AlreadyInstalled _ _)) -> pure $ Right ()
|
VLeft (V (AlreadyInstalled _ _)) -> pure $ Right ()
|
||||||
VLeft (V NoUpdate) -> pure $ Right ()
|
VLeft (V NoUpdate) -> pure $ Right ()
|
||||||
@@ -536,17 +559,7 @@ settings' = unsafePerformIO $ do
|
|||||||
, fileOutter = \_ -> pure ()
|
, fileOutter = \_ -> pure ()
|
||||||
, fancyColors = True
|
, fancyColors = True
|
||||||
}
|
}
|
||||||
newIORef $ AppState (Settings { cache = True
|
newIORef $ AppState defaultSettings
|
||||||
, noVerify = False
|
|
||||||
, keepDirs = Never
|
|
||||||
, downloader = Curl
|
|
||||||
, verbose = False
|
|
||||||
, urlSource = GHCupURL
|
|
||||||
, noNetwork = False
|
|
||||||
, gpgSetting = GPGNone
|
|
||||||
, noColor = False
|
|
||||||
, ..
|
|
||||||
})
|
|
||||||
dirs
|
dirs
|
||||||
defaultKeyBindings
|
defaultKeyBindings
|
||||||
(GHCupInfo mempty mempty mempty)
|
(GHCupInfo mempty mempty mempty)
|
||||||
@@ -605,4 +618,3 @@ getAppData mgi = runExceptT $ do
|
|||||||
flip runReaderT settings $ do
|
flip runReaderT settings $ do
|
||||||
lV <- listVersions Nothing Nothing
|
lV <- listVersions Nothing Nothing
|
||||||
pure $ BrickData (reverse lV)
|
pure $ BrickData (reverse lV)
|
||||||
|
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ data Options = Options
|
|||||||
-- global options
|
-- global options
|
||||||
optVerbose :: Maybe Bool
|
optVerbose :: Maybe Bool
|
||||||
, optCache :: Maybe Bool
|
, optCache :: Maybe Bool
|
||||||
|
, optMetaCache :: Maybe Integer
|
||||||
, optUrlSource :: Maybe URI
|
, optUrlSource :: Maybe URI
|
||||||
, optNoVerify :: Maybe Bool
|
, optNoVerify :: Maybe Bool
|
||||||
, optKeepDirs :: Maybe KeepDirs
|
, optKeepDirs :: Maybe KeepDirs
|
||||||
@@ -105,6 +106,7 @@ opts =
|
|||||||
Options
|
Options
|
||||||
<$> invertableSwitch "verbose" 'v' False (help "Enable verbosity (default: disabled)")
|
<$> invertableSwitch "verbose" 'v' False (help "Enable verbosity (default: disabled)")
|
||||||
<*> invertableSwitch "cache" 'c' False (help "Cache downloads in ~/.ghcup/cache (default: disabled)")
|
<*> invertableSwitch "cache" 'c' False (help "Cache downloads in ~/.ghcup/cache (default: disabled)")
|
||||||
|
<*> optional (option auto (long "metadata-caching" <> help "How long the yaml metadata caching interval is (in seconds), 0 to disable" <> internal))
|
||||||
<*> optional
|
<*> optional
|
||||||
(option
|
(option
|
||||||
(eitherReader parseUri)
|
(eitherReader parseUri)
|
||||||
|
|||||||
@@ -89,6 +89,18 @@ toolVersionArgument criteria tool =
|
|||||||
mv _ = "VERSION|TAG"
|
mv _ = "VERSION|TAG"
|
||||||
|
|
||||||
|
|
||||||
|
toolVersionOption :: Maybe ListCriteria -> Maybe Tool -> Parser ToolVersion
|
||||||
|
toolVersionOption criteria tool =
|
||||||
|
option (eitherReader toolVersionEither)
|
||||||
|
( sh tool
|
||||||
|
<> completer (tagCompleter (fromMaybe GHC tool) [])
|
||||||
|
<> foldMap (completer . versionCompleter criteria) tool)
|
||||||
|
where
|
||||||
|
sh (Just GHC) = long "ghc" <> metavar "GHC_VERSION|TAG"
|
||||||
|
sh (Just HLS) = long "hls" <> metavar "HLS_VERSION|TAG"
|
||||||
|
sh _ = long "version" <> metavar "VERSION|TAG"
|
||||||
|
|
||||||
|
|
||||||
versionParser :: Parser GHCTargetVersion
|
versionParser :: Parser GHCTargetVersion
|
||||||
versionParser = option
|
versionParser = option
|
||||||
(eitherReader tVersionEither)
|
(eitherReader tVersionEither)
|
||||||
@@ -196,8 +208,8 @@ platformParser s' = case MP.parse (platformP <* MP.eof) "" (T.pack s') of
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
bindistParser :: String -> Either String URI
|
uriParser :: String -> Either String URI
|
||||||
bindistParser = first show . parseURI strictURIParserOptions . UTF8.fromString
|
uriParser = first show . parseURI strictURIParserOptions . UTF8.fromString
|
||||||
|
|
||||||
|
|
||||||
absolutePathParser :: FilePath -> Either String FilePath
|
absolutePathParser :: FilePath -> Either String FilePath
|
||||||
@@ -246,18 +258,6 @@ criteriaParser s' | t == T.pack "installed" = Right ListInstalled
|
|||||||
where t = T.toLower (T.pack s')
|
where t = T.toLower (T.pack s')
|
||||||
|
|
||||||
|
|
||||||
toolVersionParser :: Parser ToolVersion
|
|
||||||
toolVersionParser = verP' <|> toolP
|
|
||||||
where
|
|
||||||
verP' = ToolVersion <$> versionParser
|
|
||||||
toolP =
|
|
||||||
ToolTag
|
|
||||||
<$> option
|
|
||||||
(eitherReader tagEither)
|
|
||||||
(short 't' <> long "tag" <> metavar "TAG" <> help "The target tag")
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
keepOnParser :: String -> Either String KeepDirs
|
keepOnParser :: String -> Either String KeepDirs
|
||||||
keepOnParser s' | t == T.pack "always" = Right Always
|
keepOnParser s' | t == T.pack "always" = Right Always
|
||||||
@@ -299,7 +299,7 @@ tagCompleter tool add = listIOCompleter $ do
|
|||||||
, fancyColors = False
|
, fancyColors = False
|
||||||
}
|
}
|
||||||
let appState = LeanAppState
|
let appState = LeanAppState
|
||||||
(Settings True False Never Curl False GHCupURL True GPGNone False)
|
(defaultSettings { noNetwork = True })
|
||||||
dirs'
|
dirs'
|
||||||
defaultKeyBindings
|
defaultKeyBindings
|
||||||
loggerConfig
|
loggerConfig
|
||||||
@@ -322,7 +322,7 @@ versionCompleter criteria tool = listIOCompleter $ do
|
|||||||
, fileOutter = mempty
|
, fileOutter = mempty
|
||||||
, fancyColors = False
|
, fancyColors = False
|
||||||
}
|
}
|
||||||
let settings = Settings True False Never Curl False GHCupURL True GPGNone False
|
let settings = defaultSettings { noNetwork = True }
|
||||||
let leanAppState = LeanAppState
|
let leanAppState = LeanAppState
|
||||||
settings
|
settings
|
||||||
dirs'
|
dirs'
|
||||||
@@ -399,7 +399,7 @@ fromVersion' (SetToolVersion v) tool = do
|
|||||||
Right pvpIn ->
|
Right pvpIn ->
|
||||||
lift (getLatestToolFor tool pvpIn dls) >>= \case
|
lift (getLatestToolFor tool pvpIn dls) >>= \case
|
||||||
Just (pvp_, vi') -> do
|
Just (pvp_, vi') -> do
|
||||||
v' <- lift $ pvpToVersion pvp_
|
v' <- lift $ pvpToVersion pvp_ ""
|
||||||
when (v' /= _tvVersion v) $ lift $ logWarn ("Assuming you meant version " <> prettyVer v')
|
when (v' /= _tvVersion v) $ lift $ logWarn ("Assuming you meant version " <> prettyVer v')
|
||||||
pure (GHCTargetVersion (_tvTarget v) v', Just vi')
|
pure (GHCTargetVersion (_tvTarget v) v', Just vi')
|
||||||
Nothing -> pure (v, vi)
|
Nothing -> pure (v, vi)
|
||||||
@@ -472,42 +472,22 @@ checkForUpdates :: ( MonadReader env m
|
|||||||
, MonadIO m
|
, MonadIO m
|
||||||
, MonadFail m
|
, MonadFail m
|
||||||
)
|
)
|
||||||
=> m ()
|
=> m [(Tool, Version)]
|
||||||
checkForUpdates = do
|
checkForUpdates = do
|
||||||
GHCupInfo { _ghcupDownloads = dls } <- getGHCupInfo
|
GHCupInfo { _ghcupDownloads = dls } <- getGHCupInfo
|
||||||
lInstalled <- listVersions Nothing (Just ListInstalled)
|
lInstalled <- listVersions Nothing (Just ListInstalled)
|
||||||
let latestInstalled tool = (fmap lVer . lastMay . filter (\lr -> lTool lr == tool)) lInstalled
|
let latestInstalled tool = (fmap lVer . lastMay . filter (\lr -> lTool lr == tool)) lInstalled
|
||||||
|
|
||||||
forM_ (getLatest dls GHCup) $ \(l, _) -> do
|
ghcup <- forMM (getLatest dls GHCup) $ \(l, _) -> do
|
||||||
(Right ghc_ver) <- pure $ version $ prettyPVP ghcUpVer
|
(Right ghcup_ver) <- pure $ version $ prettyPVP ghcUpVer
|
||||||
when (l > ghc_ver)
|
if (l > ghcup_ver) then pure $ Just (GHCup, l) else pure Nothing
|
||||||
$ logWarn $
|
|
||||||
"New GHCup version available: " <> prettyVer l <> ". To upgrade, run 'ghcup upgrade'"
|
|
||||||
|
|
||||||
forM_ (getLatest dls GHC) $ \(l, _) -> do
|
otherTools <- forM [GHC, Cabal, HLS, Stack] $ \t ->
|
||||||
let mghc_ver = latestInstalled GHC
|
forMM (getLatest dls t) $ \(l, _) -> do
|
||||||
forM mghc_ver $ \ghc_ver ->
|
let mver = latestInstalled t
|
||||||
when (l > ghc_ver)
|
forMM mver $ \ver ->
|
||||||
$ logWarn $
|
if (l > ver) then pure $ Just (t, l) else pure Nothing
|
||||||
"New GHC version available: " <> prettyVer l <> ". To upgrade, run 'ghcup install ghc " <> prettyVer l <> "'"
|
|
||||||
|
|
||||||
forM_ (getLatest dls Cabal) $ \(l, _) -> do
|
pure $ catMaybes (ghcup:otherTools)
|
||||||
let mcabal_ver = latestInstalled Cabal
|
where
|
||||||
forM mcabal_ver $ \cabal_ver ->
|
forMM a f = fmap join $ forM a f
|
||||||
when (l > cabal_ver)
|
|
||||||
$ logWarn $
|
|
||||||
"New Cabal version available: " <> prettyVer l <> ". To upgrade, run 'ghcup install cabal " <> prettyVer l <> "'"
|
|
||||||
|
|
||||||
forM_ (getLatest dls HLS) $ \(l, _) -> do
|
|
||||||
let mhls_ver = latestInstalled HLS
|
|
||||||
forM mhls_ver $ \hls_ver ->
|
|
||||||
when (l > hls_ver)
|
|
||||||
$ logWarn $
|
|
||||||
"New HLS version available: " <> prettyVer l <> ". To upgrade, run 'ghcup install hls " <> prettyVer l <> "'"
|
|
||||||
|
|
||||||
forM_ (getLatest dls Stack) $ \(l, _) -> do
|
|
||||||
let mstack_ver = latestInstalled Stack
|
|
||||||
forM mstack_ver $ \stack_ver ->
|
|
||||||
when (l > stack_ver)
|
|
||||||
$ logWarn $
|
|
||||||
"New Stack version available: " <> prettyVer l <> ". To upgrade, run 'ghcup install stack " <> prettyVer l <> "'"
|
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ import Prelude hiding ( appendFile )
|
|||||||
import System.Exit
|
import System.Exit
|
||||||
import Text.PrettyPrint.HughesPJClass ( prettyShow )
|
import Text.PrettyPrint.HughesPJClass ( prettyShow )
|
||||||
|
|
||||||
|
import URI.ByteString hiding ( uriParser )
|
||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
import Control.Exception.Safe (MonadMask)
|
import Control.Exception.Safe (MonadMask)
|
||||||
import System.FilePath (isPathSeparator)
|
import System.FilePath (isPathSeparator)
|
||||||
@@ -68,7 +69,7 @@ data GHCCompileOptions = GHCCompileOptions
|
|||||||
, bootstrapGhc :: Either Version FilePath
|
, bootstrapGhc :: Either Version FilePath
|
||||||
, jobs :: Maybe Int
|
, jobs :: Maybe Int
|
||||||
, buildConfig :: Maybe FilePath
|
, buildConfig :: Maybe FilePath
|
||||||
, patchDir :: Maybe FilePath
|
, patches :: Maybe (Either FilePath [URI])
|
||||||
, crossTarget :: Maybe Text
|
, crossTarget :: Maybe Text
|
||||||
, addConfArgs :: [Text]
|
, addConfArgs :: [Text]
|
||||||
, setCompile :: Bool
|
, setCompile :: Bool
|
||||||
@@ -84,10 +85,11 @@ data HLSCompileOptions = HLSCompileOptions
|
|||||||
, setCompile :: Bool
|
, setCompile :: Bool
|
||||||
, ovewrwiteVer :: Maybe Version
|
, ovewrwiteVer :: Maybe Version
|
||||||
, isolateDir :: Maybe FilePath
|
, isolateDir :: Maybe FilePath
|
||||||
, cabalProject :: Maybe FilePath
|
, cabalProject :: Maybe (Either FilePath URI)
|
||||||
, cabalProjectLocal :: Maybe FilePath
|
, cabalProjectLocal :: Maybe URI
|
||||||
, patchDir :: Maybe FilePath
|
, patches :: Maybe (Either FilePath [URI])
|
||||||
, targetGHCs :: [ToolVersion]
|
, targetGHCs :: [ToolVersion]
|
||||||
|
, cabalArgs :: [Text]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -148,7 +150,10 @@ Examples:
|
|||||||
These need to be available in PATH prior to compilation.
|
These need to be available in PATH prior to compilation.
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
ghcup compile hls -v 1.4.0 -j 12 8.10.5 8.10.7 9.0.1|]
|
# compile 1.4.0 for ghc 8.10.5 and 8.10.7
|
||||||
|
ghcup compile hls -v 1.4.0 -j 12 --ghc 8.10.5 --ghc 8.10.7
|
||||||
|
# compile from master for ghc 8.10.7, linking everything dynamically
|
||||||
|
ghcup compile hls -g master -j 12 --ghc 8.10.7 -- --ghc-options='-dynamic'|]
|
||||||
|
|
||||||
|
|
||||||
ghcCompileOpts :: Parser GHCCompileOptions
|
ghcCompileOpts :: Parser GHCCompileOptions
|
||||||
@@ -195,13 +200,23 @@ ghcCompileOpts =
|
|||||||
"Absolute path to build config file"
|
"Absolute path to build config file"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
<*> optional
|
<*> (optional
|
||||||
(option
|
(
|
||||||
str
|
(fmap Right $ many $ option
|
||||||
(short 'p' <> long "patchdir" <> metavar "PATCH_DIR" <> help
|
(eitherReader uriParser)
|
||||||
"Absolute path to patch directory (applies all .patch and .diff files in order using -p1)"
|
(long "patch" <> metavar "PATCH_URI" <> help
|
||||||
|
"URI to a patch (https/http/file)"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
<|>
|
||||||
|
(fmap Left $ option
|
||||||
|
str
|
||||||
|
(short 'p' <> long "patchdir" <> metavar "PATCH_DIR" <> help
|
||||||
|
"Absolute path to patch directory (applies all .patch and .diff files in order using -p1)"
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
)
|
||||||
<*> optional
|
<*> optional
|
||||||
(option
|
(option
|
||||||
str
|
str
|
||||||
@@ -296,26 +311,37 @@ hlsCompileOpts =
|
|||||||
)
|
)
|
||||||
<*> optional
|
<*> optional
|
||||||
(option
|
(option
|
||||||
str
|
((fmap Right $ eitherReader uriParser) <|> (fmap Left str))
|
||||||
(long "cabal-project" <> metavar "CABAL_PROJECT" <> help
|
(long "cabal-project" <> metavar "CABAL_PROJECT" <> help
|
||||||
"If relative, specifies the path to cabal.project inside the unpacked HLS tarball/checkout. If absolute, will copy the file over."
|
"If relative filepath, specifies the path to cabal.project inside the unpacked HLS tarball/checkout. Otherwise expects a full URI with https/http/file scheme."
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
<*> optional
|
<*> optional
|
||||||
(option
|
(option
|
||||||
(eitherReader absolutePathParser)
|
(eitherReader uriParser)
|
||||||
(long "cabal-project-local" <> metavar "CABAL_PROJECT_LOCAL" <> help
|
(long "cabal-project-local" <> metavar "CABAL_PROJECT_LOCAL" <> help
|
||||||
"Absolute path to a cabal.project.local to be used for the build. Will be copied over."
|
"URI (https/http/file) to a cabal.project.local to be used for the build. Will be copied over."
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
<*> optional
|
<*> (optional
|
||||||
(option
|
(
|
||||||
(eitherReader absolutePathParser)
|
(fmap Right $ many $ option
|
||||||
(short 'p' <> long "patchdir" <> metavar "PATCH_DIR" <> help
|
(eitherReader uriParser)
|
||||||
"Absolute path to patch directory (applies all .patch and .diff files in order using -p1)"
|
(long "patch" <> metavar "PATCH_URI" <> help
|
||||||
|
"URI to a patch (https/http/file)"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
<|>
|
||||||
|
(fmap Left $ option
|
||||||
|
str
|
||||||
|
(short 'p' <> long "patchdir" <> metavar "PATCH_DIR" <> help
|
||||||
|
"Absolute path to patch directory (applies all .patch and .diff files in order using -p1)"
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
<*> some (toolVersionArgument Nothing (Just GHC))
|
)
|
||||||
|
<*> some (toolVersionOption Nothing (Just GHC))
|
||||||
|
<*> many (argument str (metavar "CABAL_ARGS" <> help "Additional arguments to cabal install, prefix with '-- ' (longopts)"))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -403,11 +429,11 @@ compile :: ( Monad m
|
|||||||
)
|
)
|
||||||
=> CompileCommand
|
=> CompileCommand
|
||||||
-> Settings
|
-> Settings
|
||||||
|
-> Dirs
|
||||||
-> (forall eff a . ReaderT AppState m (VEither eff a) -> m (VEither eff a))
|
-> (forall eff a . ReaderT AppState m (VEither eff a) -> m (VEither eff a))
|
||||||
-> (ReaderT LeanAppState m () -> m ())
|
-> (ReaderT LeanAppState m () -> m ())
|
||||||
-> m ExitCode
|
-> m ExitCode
|
||||||
compile compileCommand settings runAppState runLogger = do
|
compile compileCommand settings Dirs{..} runAppState runLogger = do
|
||||||
VRight Dirs{ .. } <- runAppState (VRight <$> getDirs)
|
|
||||||
case compileCommand of
|
case compileCommand of
|
||||||
(CompileHLS HLSCompileOptions { .. }) -> do
|
(CompileHLS HLSCompileOptions { .. }) -> do
|
||||||
runCompileHLS runAppState (do
|
runCompileHLS runAppState (do
|
||||||
@@ -430,7 +456,8 @@ compile compileCommand settings runAppState runLogger = do
|
|||||||
isolateDir
|
isolateDir
|
||||||
cabalProject
|
cabalProject
|
||||||
cabalProjectLocal
|
cabalProjectLocal
|
||||||
patchDir
|
patches
|
||||||
|
cabalArgs
|
||||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||||
let vi = getVersionInfo targetVer HLS dls
|
let vi = getVersionInfo targetVer HLS dls
|
||||||
when setCompile $ void $ liftE $
|
when setCompile $ void $ liftE $
|
||||||
@@ -477,7 +504,7 @@ compile compileCommand settings runAppState runLogger = do
|
|||||||
bootstrapGhc
|
bootstrapGhc
|
||||||
jobs
|
jobs
|
||||||
buildConfig
|
buildConfig
|
||||||
patchDir
|
patches
|
||||||
addConfArgs
|
addConfArgs
|
||||||
buildFlavour
|
buildFlavour
|
||||||
hadrian
|
hadrian
|
||||||
|
|||||||
@@ -122,6 +122,7 @@ updateSettings config' settings = do
|
|||||||
mergeConf :: UserSettings -> Settings -> Settings
|
mergeConf :: UserSettings -> Settings -> Settings
|
||||||
mergeConf UserSettings{..} Settings{..} =
|
mergeConf UserSettings{..} Settings{..} =
|
||||||
let cache' = fromMaybe cache uCache
|
let cache' = fromMaybe cache uCache
|
||||||
|
metaCache' = fromMaybe metaCache uMetaCache
|
||||||
noVerify' = fromMaybe noVerify uNoVerify
|
noVerify' = fromMaybe noVerify uNoVerify
|
||||||
keepDirs' = fromMaybe keepDirs uKeepDirs
|
keepDirs' = fromMaybe keepDirs uKeepDirs
|
||||||
downloader' = fromMaybe downloader uDownloader
|
downloader' = fromMaybe downloader uDownloader
|
||||||
@@ -129,7 +130,7 @@ updateSettings config' settings = do
|
|||||||
urlSource' = fromMaybe urlSource uUrlSource
|
urlSource' = fromMaybe urlSource uUrlSource
|
||||||
noNetwork' = fromMaybe noNetwork uNoNetwork
|
noNetwork' = fromMaybe noNetwork uNoNetwork
|
||||||
gpgSetting' = fromMaybe gpgSetting uGPGSetting
|
gpgSetting' = fromMaybe gpgSetting uGPGSetting
|
||||||
in Settings cache' noVerify' keepDirs' downloader' verbose' urlSource' noNetwork' gpgSetting' noColor
|
in Settings cache' metaCache' noVerify' keepDirs' downloader' verbose' urlSource' noNetwork' gpgSetting' noColor
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ describe_result = $( LitE . StringL <$>
|
|||||||
runIO (do
|
runIO (do
|
||||||
CapturedProcess{..} <- do
|
CapturedProcess{..} <- do
|
||||||
dirs <- liftIO getAllDirs
|
dirs <- liftIO getAllDirs
|
||||||
let settings = AppState (Settings True False Never Curl False GHCupURL False GPGNone False)
|
let settings = AppState (defaultSettings { noNetwork = True })
|
||||||
dirs
|
dirs
|
||||||
defaultKeyBindings
|
defaultKeyBindings
|
||||||
flip runReaderT settings $ executeOut "git" ["describe"] Nothing
|
flip runReaderT settings $ executeOut "git" ["describe"] Nothing
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ import Options.Applicative.Help.Pretty ( text )
|
|||||||
import Prelude hiding ( appendFile )
|
import Prelude hiding ( appendFile )
|
||||||
import System.Exit
|
import System.Exit
|
||||||
import Text.PrettyPrint.HughesPJClass ( prettyShow )
|
import Text.PrettyPrint.HughesPJClass ( prettyShow )
|
||||||
import URI.ByteString
|
import URI.ByteString hiding ( uriParser )
|
||||||
|
|
||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
|
|
||||||
@@ -187,7 +187,7 @@ installOpts tool =
|
|||||||
<*> ( ( (,)
|
<*> ( ( (,)
|
||||||
<$> optional
|
<$> optional
|
||||||
(option
|
(option
|
||||||
(eitherReader bindistParser)
|
(eitherReader uriParser)
|
||||||
(short 'u' <> long "url" <> metavar "BINDIST_URL" <> help
|
(short 'u' <> long "url" <> metavar "BINDIST_URL" <> help
|
||||||
"Install the specified version from this bindist"
|
"Install the specified version from this bindist"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import GHCup.Download
|
|||||||
import GHCup.Errors
|
import GHCup.Errors
|
||||||
import GHCup.Platform
|
import GHCup.Platform
|
||||||
import GHCup.Types
|
import GHCup.Types
|
||||||
|
import GHCup.Types.Optics hiding ( toolRequirements )
|
||||||
import GHCup.Utils
|
import GHCup.Utils
|
||||||
import GHCup.Utils.Logger
|
import GHCup.Utils.Logger
|
||||||
import GHCup.Utils.Prelude
|
import GHCup.Utils.Prelude
|
||||||
@@ -39,6 +40,7 @@ import Data.Aeson.Encode.Pretty ( encodePretty )
|
|||||||
import Data.Either
|
import Data.Either
|
||||||
import Data.Functor
|
import Data.Functor
|
||||||
import Data.Maybe
|
import Data.Maybe
|
||||||
|
import Data.Versions
|
||||||
import GHC.IO.Encoding
|
import GHC.IO.Encoding
|
||||||
import Haskus.Utils.Variant.Excepts
|
import Haskus.Utils.Variant.Excepts
|
||||||
import Language.Haskell.TH
|
import Language.Haskell.TH
|
||||||
@@ -55,6 +57,7 @@ import qualified Data.ByteString as B
|
|||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
import qualified Data.Text.IO as T
|
import qualified Data.Text.IO as T
|
||||||
import qualified Data.Text.Encoding as E
|
import qualified Data.Text.Encoding as E
|
||||||
|
import qualified GHCup.Types as Types
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -72,15 +75,16 @@ toSettings options = do
|
|||||||
where
|
where
|
||||||
mergeConf :: Options -> UserSettings -> Bool -> (Settings, KeyBindings)
|
mergeConf :: Options -> UserSettings -> Bool -> (Settings, KeyBindings)
|
||||||
mergeConf Options{..} UserSettings{..} noColor =
|
mergeConf Options{..} UserSettings{..} noColor =
|
||||||
let cache = fromMaybe (fromMaybe False uCache) optCache
|
let cache = fromMaybe (fromMaybe (Types.cache defaultSettings) uCache) optCache
|
||||||
noVerify = fromMaybe (fromMaybe False uNoVerify) optNoVerify
|
metaCache = fromMaybe (fromMaybe (Types.metaCache defaultSettings) uMetaCache) optMetaCache
|
||||||
verbose = fromMaybe (fromMaybe False uVerbose) optVerbose
|
noVerify = fromMaybe (fromMaybe (Types.noVerify defaultSettings) uNoVerify) optNoVerify
|
||||||
keepDirs = fromMaybe (fromMaybe Errors uKeepDirs) optKeepDirs
|
verbose = fromMaybe (fromMaybe (Types.verbose defaultSettings) uVerbose) optVerbose
|
||||||
|
keepDirs = fromMaybe (fromMaybe (Types.keepDirs defaultSettings) uKeepDirs) optKeepDirs
|
||||||
downloader = fromMaybe (fromMaybe defaultDownloader uDownloader) optsDownloader
|
downloader = fromMaybe (fromMaybe defaultDownloader uDownloader) optsDownloader
|
||||||
keyBindings = maybe defaultKeyBindings mergeKeys uKeyBindings
|
keyBindings = maybe defaultKeyBindings mergeKeys uKeyBindings
|
||||||
urlSource = maybe (fromMaybe GHCupURL uUrlSource) OwnSource optUrlSource
|
urlSource = maybe (fromMaybe (Types.urlSource defaultSettings) uUrlSource) OwnSource optUrlSource
|
||||||
noNetwork = fromMaybe (fromMaybe False uNoNetwork) optNoNetwork
|
noNetwork = fromMaybe (fromMaybe (Types.noNetwork defaultSettings) uNoNetwork) optNoNetwork
|
||||||
gpgSetting = fromMaybe (fromMaybe GPGNone uGPGSetting) optGpg
|
gpgSetting = fromMaybe (fromMaybe (Types.gpgSetting defaultSettings) uGPGSetting) optGpg
|
||||||
in (Settings {..}, keyBindings)
|
in (Settings {..}, keyBindings)
|
||||||
#if defined(INTERNAL_DOWNLOADER)
|
#if defined(INTERNAL_DOWNLOADER)
|
||||||
defaultDownloader = Internal
|
defaultDownloader = Internal
|
||||||
@@ -189,7 +193,7 @@ Report bugs at <https://gitlab.haskell.org/haskell/ghcup-hs/issues>|]
|
|||||||
-------------------------
|
-------------------------
|
||||||
|
|
||||||
|
|
||||||
appState = do
|
let appState = do
|
||||||
pfreq <- (
|
pfreq <- (
|
||||||
runLogger . runE @'[NoCompatiblePlatform, NoCompatibleArch, DistroNotFound] . liftE $ platformRequest
|
runLogger . runE @'[NoCompatiblePlatform, NoCompatibleArch, DistroNotFound] . liftE $ platformRequest
|
||||||
) >>= \case
|
) >>= \case
|
||||||
@@ -225,8 +229,28 @@ Report bugs at <https://gitlab.haskell.org/haskell/ghcup-hs/issues>|]
|
|||||||
#if defined(BRICK)
|
#if defined(BRICK)
|
||||||
Interactive -> pure ()
|
Interactive -> pure ()
|
||||||
#endif
|
#endif
|
||||||
|
-- check for new tools
|
||||||
_ -> lookupEnv "GHCUP_SKIP_UPDATE_CHECK" >>= \case
|
_ -> lookupEnv "GHCUP_SKIP_UPDATE_CHECK" >>= \case
|
||||||
Nothing -> runReaderT checkForUpdates s'
|
Nothing -> void . flip runReaderT s' . runE @'[TagNotFound, NextVerNotFound, NoToolVersionSet] $ do
|
||||||
|
newTools <- lift checkForUpdates
|
||||||
|
forM_ newTools $ \newTool@(t, l) -> do
|
||||||
|
-- https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/283
|
||||||
|
alreadyInstalling' <- alreadyInstalling optCommand newTool
|
||||||
|
when (not alreadyInstalling') $
|
||||||
|
case t of
|
||||||
|
GHCup -> runLogger $
|
||||||
|
logWarn ("New GHCup version available: "
|
||||||
|
<> prettyVer l
|
||||||
|
<> ". To upgrade, run 'ghcup upgrade'")
|
||||||
|
_ -> runLogger $
|
||||||
|
logWarn ("New "
|
||||||
|
<> T.pack (prettyShow t)
|
||||||
|
<> " version available. "
|
||||||
|
<> "To upgrade, run 'ghcup install "
|
||||||
|
<> T.pack (prettyShow t)
|
||||||
|
<> " "
|
||||||
|
<> prettyVer l
|
||||||
|
<> "'")
|
||||||
Just _ -> pure ()
|
Just _ -> pure ()
|
||||||
|
|
||||||
-- TODO: always run for windows
|
-- TODO: always run for windows
|
||||||
@@ -268,7 +292,7 @@ Report bugs at <https://gitlab.haskell.org/haskell/ghcup-hs/issues>|]
|
|||||||
List lo -> list lo no_color runAppState
|
List lo -> list lo no_color runAppState
|
||||||
Rm rmCommand -> rm rmCommand runAppState runLogger
|
Rm rmCommand -> rm rmCommand runAppState runLogger
|
||||||
DInfo -> dinfo runAppState runLogger
|
DInfo -> dinfo runAppState runLogger
|
||||||
Compile compileCommand -> compile compileCommand settings runAppState runLogger
|
Compile compileCommand -> compile compileCommand settings dirs runAppState runLogger
|
||||||
Config configCommand -> config configCommand settings keybindings runLogger
|
Config configCommand -> config configCommand settings keybindings runLogger
|
||||||
Whereis whereisOptions
|
Whereis whereisOptions
|
||||||
whereisCommand -> whereis whereisCommand whereisOptions runAppState leanAppstate runLogger
|
whereisCommand -> whereis whereisCommand whereisOptions runAppState leanAppstate runLogger
|
||||||
@@ -285,4 +309,55 @@ Report bugs at <https://gitlab.haskell.org/haskell/ghcup-hs/issues>|]
|
|||||||
|
|
||||||
pure ()
|
pure ()
|
||||||
|
|
||||||
|
where
|
||||||
|
alreadyInstalling :: ( HasLog env
|
||||||
|
, MonadFail m
|
||||||
|
, MonadReader env m
|
||||||
|
, HasGHCupInfo env
|
||||||
|
, HasDirs env
|
||||||
|
, MonadThrow m
|
||||||
|
, MonadIO m
|
||||||
|
, MonadCatch m
|
||||||
|
)
|
||||||
|
=> Command
|
||||||
|
-> (Tool, Version)
|
||||||
|
-> Excepts
|
||||||
|
'[ TagNotFound
|
||||||
|
, NextVerNotFound
|
||||||
|
, NoToolVersionSet
|
||||||
|
] m Bool
|
||||||
|
alreadyInstalling (Install (Right InstallOptions{..})) (GHC, ver) = cmp' GHC instVer ver
|
||||||
|
alreadyInstalling (Install (Left (InstallGHC InstallOptions{..}))) (GHC, ver) = cmp' GHC instVer ver
|
||||||
|
alreadyInstalling (Install (Left (InstallCabal InstallOptions{..}))) (Cabal, ver) = cmp' Cabal instVer ver
|
||||||
|
alreadyInstalling (Install (Left (InstallHLS InstallOptions{..}))) (HLS, ver) = cmp' HLS instVer ver
|
||||||
|
alreadyInstalling (Install (Left (InstallStack InstallOptions{..}))) (Stack, ver) = cmp' Stack instVer ver
|
||||||
|
alreadyInstalling (Compile (CompileGHC GHCCompileOptions{ ovewrwiteVer = Just over }))
|
||||||
|
(GHC, ver) = cmp' GHC (Just $ ToolVersion (mkTVer over)) ver
|
||||||
|
alreadyInstalling (Compile (CompileGHC GHCCompileOptions{ targetGhc = Left tver }))
|
||||||
|
(GHC, ver) = cmp' GHC (Just $ ToolVersion (mkTVer tver)) ver
|
||||||
|
alreadyInstalling (Compile (CompileHLS HLSCompileOptions{ ovewrwiteVer = Just over }))
|
||||||
|
(HLS, ver) = cmp' HLS (Just $ ToolVersion (mkTVer over)) ver
|
||||||
|
alreadyInstalling (Compile (CompileHLS HLSCompileOptions{ targetHLS = Left tver }))
|
||||||
|
(HLS, ver) = cmp' HLS (Just $ ToolVersion (mkTVer tver)) ver
|
||||||
|
alreadyInstalling _ _ = pure False
|
||||||
|
|
||||||
|
cmp' :: ( HasLog env
|
||||||
|
, MonadFail m
|
||||||
|
, MonadReader env m
|
||||||
|
, HasGHCupInfo env
|
||||||
|
, HasDirs env
|
||||||
|
, MonadThrow m
|
||||||
|
, MonadIO m
|
||||||
|
, MonadCatch m
|
||||||
|
)
|
||||||
|
=> Tool
|
||||||
|
-> Maybe ToolVersion
|
||||||
|
-> Version
|
||||||
|
-> Excepts
|
||||||
|
'[ TagNotFound
|
||||||
|
, NextVerNotFound
|
||||||
|
, NoToolVersionSet
|
||||||
|
] m Bool
|
||||||
|
cmp' tool instVer ver = do
|
||||||
|
(v, _) <- liftE $ fromVersion instVer tool
|
||||||
|
pure (v == mkTVer ver)
|
||||||
|
|||||||
@@ -8,7 +8,9 @@ package ghcup
|
|||||||
tests: True
|
tests: True
|
||||||
flags: +tui
|
flags: +tui
|
||||||
|
|
||||||
constraints: http-io-streams -brotli
|
constraints: http-io-streams -brotli,
|
||||||
|
any.Cabal ==3.6.2.0,
|
||||||
|
any.aeson >= 2.0.1.0
|
||||||
|
|
||||||
package libarchive
|
package libarchive
|
||||||
flags: -system-libarchive
|
flags: -system-libarchive
|
||||||
@@ -19,6 +21,9 @@ package aeson-pretty
|
|||||||
package cabal-plan
|
package cabal-plan
|
||||||
flags: -exe
|
flags: -exe
|
||||||
|
|
||||||
|
package aeson
|
||||||
|
flags: +ordered-keymap
|
||||||
|
|
||||||
allow-newer: base, ghc-prim, template-haskell, language-c
|
allow-newer: base, ghc-prim, template-haskell, language-c
|
||||||
|
|
||||||
with-compiler: ghc-8.10.7
|
with-compiler: ghc-8.10.7
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
active-repositories: hackage.haskell.org:merge
|
active-repositories: hackage.haskell.org:merge
|
||||||
constraints: any.Cabal ==3.2.1.0 || ==3.6.1.0,
|
constraints: any.Cabal ==3.6.2.0,
|
||||||
Cabal -bundled-binary-generic,
|
Cabal -bundled-binary-generic,
|
||||||
any.HUnit ==1.6.2.0,
|
any.HUnit ==1.6.2.0,
|
||||||
any.HsOpenSSL ==0.11.7.2,
|
any.HsOpenSSL ==0.11.7.2,
|
||||||
HsOpenSSL -fast-bignum -homebrew-openssl -macports-openssl -use-pkg-config,
|
HsOpenSSL -fast-bignum -homebrew-openssl -macports-openssl -use-pkg-config,
|
||||||
any.HsYAML ==0.2.1.0,
|
any.OneTuple ==0.3.1,
|
||||||
HsYAML -exe,
|
|
||||||
any.HsYAML-aeson ==0.2.0.0,
|
|
||||||
any.QuickCheck ==2.14.2,
|
any.QuickCheck ==2.14.2,
|
||||||
QuickCheck -old-random +templatehaskell,
|
QuickCheck -old-random +templatehaskell,
|
||||||
any.StateVar ==1.2.2,
|
any.StateVar ==1.2.2,
|
||||||
any.aeson ==1.5.6.0,
|
any.abstract-deque ==0.3,
|
||||||
aeson -bytestring-builder -cffi -developer -fast,
|
abstract-deque -usecas,
|
||||||
any.aeson-pretty ==0.8.8,
|
any.aeson ==2.0.1.0,
|
||||||
|
aeson -bytestring-builder -cffi +ordered-keymap,
|
||||||
|
any.aeson-pretty ==0.8.9,
|
||||||
aeson-pretty +lib-only,
|
aeson-pretty +lib-only,
|
||||||
any.alex ==3.2.6,
|
any.alex ==3.2.6,
|
||||||
alex +small_base,
|
alex +small_base,
|
||||||
@@ -22,28 +22,30 @@ constraints: any.Cabal ==3.2.1.0 || ==3.6.1.0,
|
|||||||
ansi-wl-pprint -example,
|
ansi-wl-pprint -example,
|
||||||
any.array ==0.5.4.0,
|
any.array ==0.5.4.0,
|
||||||
any.assoc ==1.0.2,
|
any.assoc ==1.0.2,
|
||||||
any.async ==2.2.3,
|
any.async ==2.2.4,
|
||||||
async -bench,
|
async -bench,
|
||||||
|
any.atomic-primops ==0.8.4,
|
||||||
|
atomic-primops -debug,
|
||||||
any.attoparsec ==0.13.2.5,
|
any.attoparsec ==0.13.2.5,
|
||||||
attoparsec -developer,
|
attoparsec -developer,
|
||||||
any.base ==4.14.3.0,
|
any.base ==4.14.3.0,
|
||||||
any.base-compat ==0.12.0,
|
any.base-compat ==0.12.1,
|
||||||
any.base-compat-batteries ==0.12.0,
|
any.base-compat-batteries ==0.12.1,
|
||||||
any.base-orphans ==0.8.5,
|
any.base-orphans ==0.8.6,
|
||||||
any.base16-bytestring ==1.0.1.0,
|
any.base16-bytestring ==1.0.2.0,
|
||||||
any.base64-bytestring ==1.1.0.0,
|
any.base64-bytestring ==1.1.0.0,
|
||||||
any.bifunctors ==5.5.11,
|
any.bifunctors ==5.5.11,
|
||||||
bifunctors +semigroups +tagged,
|
bifunctors +semigroups +tagged,
|
||||||
any.binary ==0.8.8.0,
|
any.binary ==0.8.8.0,
|
||||||
any.blaze-builder ==0.4.2.1,
|
any.blaze-builder ==0.4.2.2,
|
||||||
any.brick ==0.64.1,
|
any.brick ==0.64.2,
|
||||||
brick -demos,
|
brick -demos,
|
||||||
any.bytestring ==0.10.12.0,
|
any.bytestring ==0.10.12.0,
|
||||||
any.bz2 ==1.0.1.0,
|
any.bz2 ==1.0.1.0,
|
||||||
bz2 -cross +with-bzlib,
|
bz2 -cross +with-bzlib,
|
||||||
any.c2hs ==0.28.8,
|
any.c2hs ==0.28.8,
|
||||||
c2hs +base3 -regression,
|
c2hs +base3 -regression,
|
||||||
any.cabal-plan ==0.7.2.0,
|
any.cabal-plan ==0.7.2.1,
|
||||||
cabal-plan -_ -exe -license-report,
|
cabal-plan -_ -exe -license-report,
|
||||||
any.call-stack ==0.4.0,
|
any.call-stack ==0.4.0,
|
||||||
any.case-insensitive ==1.2.1.0,
|
any.case-insensitive ==1.2.1.0,
|
||||||
@@ -66,7 +68,7 @@ constraints: any.Cabal ==3.2.1.0 || ==3.6.1.0,
|
|||||||
any.cpphs ==1.20.9.1,
|
any.cpphs ==1.20.9.1,
|
||||||
cpphs -old-locale,
|
cpphs -old-locale,
|
||||||
any.cryptohash-sha1 ==0.11.100.1,
|
any.cryptohash-sha1 ==0.11.100.1,
|
||||||
any.cryptohash-sha256 ==0.11.102.0,
|
any.cryptohash-sha256 ==0.11.102.1,
|
||||||
cryptohash-sha256 -exe +use-cbits,
|
cryptohash-sha256 -exe +use-cbits,
|
||||||
any.data-clist ==0.1.2.3,
|
any.data-clist ==0.1.2.3,
|
||||||
any.data-fix ==0.3.2,
|
any.data-fix ==0.3.2,
|
||||||
@@ -80,17 +82,19 @@ constraints: any.Cabal ==3.2.1.0 || ==3.6.1.0,
|
|||||||
any.exceptions ==0.10.4,
|
any.exceptions ==0.10.4,
|
||||||
any.filepath ==1.4.2.1,
|
any.filepath ==1.4.2.1,
|
||||||
any.free ==5.1.7,
|
any.free ==5.1.7,
|
||||||
|
any.fusion-plugin-types ==0.1.0,
|
||||||
any.generic-arbitrary ==0.1.0,
|
any.generic-arbitrary ==0.1.0,
|
||||||
any.ghc-boot-th ==8.10.7,
|
any.ghc-boot-th ==8.10.7,
|
||||||
any.ghc-byteorder ==4.11.0.0.10,
|
any.ghc-byteorder ==4.11.0.0.10,
|
||||||
any.ghc-prim ==0.6.1,
|
any.ghc-prim ==0.6.1,
|
||||||
any.happy ==1.20.0,
|
any.happy ==1.20.0,
|
||||||
any.hashable ==1.3.3.0,
|
any.hashable ==1.3.5.0,
|
||||||
hashable +integer-gmp -random-initial-seed,
|
hashable +integer-gmp -random-initial-seed,
|
||||||
any.haskus-utils-data ==1.4,
|
any.haskus-utils-data ==1.4,
|
||||||
any.haskus-utils-types ==1.5.1,
|
any.haskus-utils-types ==1.5.1,
|
||||||
any.haskus-utils-variant ==3.1,
|
any.haskus-utils-variant ==3.2.1,
|
||||||
any.hsc2hs ==0.68.7,
|
any.heaps ==0.4,
|
||||||
|
any.hsc2hs ==0.68.8,
|
||||||
hsc2hs -in-ghc-tree,
|
hsc2hs -in-ghc-tree,
|
||||||
any.hspec ==2.7.10,
|
any.hspec ==2.7.10,
|
||||||
any.hspec-core ==2.7.10,
|
any.hspec-core ==2.7.10,
|
||||||
@@ -100,8 +104,8 @@ constraints: any.Cabal ==3.2.1.0 || ==3.6.1.0,
|
|||||||
any.http-io-streams ==0.1.6.0,
|
any.http-io-streams ==0.1.6.0,
|
||||||
http-io-streams -brotli +fast-xor,
|
http-io-streams -brotli +fast-xor,
|
||||||
any.indexed-profunctors ==0.1.1,
|
any.indexed-profunctors ==0.1.1,
|
||||||
any.indexed-traversable ==0.1.1,
|
any.indexed-traversable ==0.1.2,
|
||||||
any.indexed-traversable-instances ==0.1,
|
any.indexed-traversable-instances ==0.1.1,
|
||||||
any.integer-gmp ==1.0.3.0,
|
any.integer-gmp ==1.0.3.0,
|
||||||
any.integer-logarithms ==1.0.3.1,
|
any.integer-logarithms ==1.0.3.1,
|
||||||
integer-logarithms -check-bounds +integer-gmp,
|
integer-logarithms -check-bounds +integer-gmp,
|
||||||
@@ -109,16 +113,20 @@ constraints: any.Cabal ==3.2.1.0 || ==3.6.1.0,
|
|||||||
io-streams +network -nointeractivetests +zlib,
|
io-streams +network -nointeractivetests +zlib,
|
||||||
any.language-c ==0.9.0.1,
|
any.language-c ==0.9.0.1,
|
||||||
language-c -allwarnings +iecfpextension +usebytestrings,
|
language-c -allwarnings +iecfpextension +usebytestrings,
|
||||||
any.libarchive ==3.0.3.0,
|
any.libarchive ==3.0.3.1,
|
||||||
libarchive -cross -low-memory -system-libarchive,
|
libarchive -cross -low-memory -system-libarchive,
|
||||||
|
any.libyaml-streamly ==0.2.0,
|
||||||
|
libyaml-streamly -no-unicode -system-libyaml,
|
||||||
|
any.lockfree-queue ==0.2.3.1,
|
||||||
any.lzma-static ==5.2.5.4,
|
any.lzma-static ==5.2.5.4,
|
||||||
any.megaparsec ==9.0.1,
|
any.megaparsec ==9.0.1,
|
||||||
megaparsec -dev,
|
megaparsec -dev,
|
||||||
any.microlens ==0.4.12.0,
|
any.microlens ==0.4.12.0,
|
||||||
any.microlens-mtl ==0.2.0.1,
|
any.microlens-mtl ==0.2.0.1,
|
||||||
any.microlens-th ==0.4.3.10,
|
any.microlens-th ==0.4.3.10,
|
||||||
|
any.monad-control ==1.0.3.1,
|
||||||
any.mtl ==2.2.2,
|
any.mtl ==2.2.2,
|
||||||
any.network ==3.1.2.2,
|
any.network ==3.1.2.5,
|
||||||
network -devel,
|
network -devel,
|
||||||
any.network-uri ==2.6.4.1,
|
any.network-uri ==2.6.4.1,
|
||||||
any.openssl-streams ==1.2.3.0,
|
any.openssl-streams ==1.2.3.0,
|
||||||
@@ -129,7 +137,7 @@ constraints: any.Cabal ==3.2.1.0 || ==3.6.1.0,
|
|||||||
any.optics-th ==0.4,
|
any.optics-th ==0.4,
|
||||||
any.optparse-applicative ==0.16.1.0,
|
any.optparse-applicative ==0.16.1.0,
|
||||||
optparse-applicative +process,
|
optparse-applicative +process,
|
||||||
any.os-release ==1.0.2,
|
any.os-release ==1.0.2.1,
|
||||||
os-release -devel,
|
os-release -devel,
|
||||||
any.parallel ==3.2.2.0,
|
any.parallel ==3.2.2.0,
|
||||||
any.parsec ==3.1.14.0,
|
any.parsec ==3.1.14.0,
|
||||||
@@ -138,30 +146,36 @@ constraints: any.Cabal ==3.2.1.0 || ==3.6.1.0,
|
|||||||
any.polyparse ==1.13,
|
any.polyparse ==1.13,
|
||||||
any.pretty ==1.1.3.6,
|
any.pretty ==1.1.3.6,
|
||||||
any.pretty-terminal ==0.1.0.0,
|
any.pretty-terminal ==0.1.0.0,
|
||||||
any.primitive ==0.7.2.0,
|
any.primitive ==0.7.3.0,
|
||||||
any.process ==1.6.13.2,
|
any.process ==1.6.13.2,
|
||||||
any.profunctors ==5.6.2,
|
any.profunctors ==5.6.2,
|
||||||
any.quickcheck-arbitrary-adt ==0.3.1.0,
|
any.quickcheck-arbitrary-adt ==0.3.1.0,
|
||||||
any.quickcheck-io ==0.2.0,
|
any.quickcheck-io ==0.2.0,
|
||||||
any.random ==1.2.1,
|
any.random ==1.2.1,
|
||||||
any.recursion-schemes ==5.2.2.1,
|
any.recursion-schemes ==5.2.2.2,
|
||||||
recursion-schemes +template-haskell,
|
recursion-schemes +template-haskell,
|
||||||
any.regex-base ==0.94.0.1,
|
any.regex-base ==0.94.0.1,
|
||||||
any.regex-posix ==0.96.0.1,
|
any.regex-posix ==0.96.0.1,
|
||||||
regex-posix -_regex-posix-clib,
|
regex-posix -_regex-posix-clib,
|
||||||
any.resourcet ==1.2.4.3,
|
any.resourcet ==1.2.4.3,
|
||||||
|
any.retry ==0.8.1.2,
|
||||||
|
retry -lib-werror,
|
||||||
any.rts ==1.0.1,
|
any.rts ==1.0.1,
|
||||||
any.safe ==0.3.19,
|
any.safe ==0.3.19,
|
||||||
any.safe-exceptions ==0.1.7.2,
|
any.safe-exceptions ==0.1.7.2,
|
||||||
any.scientific ==0.3.7.0,
|
any.scientific ==0.3.7.0,
|
||||||
scientific -bytestring-builder -integer-simple,
|
scientific -bytestring-builder -integer-simple,
|
||||||
any.semigroupoids ==5.3.5,
|
any.semialign ==1.2.0.1,
|
||||||
|
semialign +semigroupoids,
|
||||||
|
any.semigroupoids ==5.3.6,
|
||||||
semigroupoids +comonad +containers +contravariant +distributive +tagged +unordered-containers,
|
semigroupoids +comonad +containers +contravariant +distributive +tagged +unordered-containers,
|
||||||
any.setenv ==0.1.1.3,
|
any.setenv ==0.1.1.3,
|
||||||
any.split ==0.2.3.4,
|
any.split ==0.2.3.4,
|
||||||
any.splitmix ==0.1.0.3,
|
any.splitmix ==0.1.0.4,
|
||||||
splitmix -optimised-mixer,
|
splitmix -optimised-mixer,
|
||||||
any.stm ==2.5.0.1,
|
any.stm ==2.5.0.1,
|
||||||
|
any.streamly ==0.8.0,
|
||||||
|
streamly -debug -dev -fusion-plugin -has-llvm -inspection -no-fusion +opt -streamk -use-c-malloc,
|
||||||
any.strict ==0.4.0.1,
|
any.strict ==0.4.0.1,
|
||||||
strict +assoc,
|
strict +assoc,
|
||||||
any.strict-base ==0.4.0.0,
|
any.strict-base ==0.4.0.0,
|
||||||
@@ -187,14 +201,14 @@ constraints: any.Cabal ==3.2.1.0 || ==3.6.1.0,
|
|||||||
any.transformers ==0.5.6.2,
|
any.transformers ==0.5.6.2,
|
||||||
any.transformers-base ==0.4.6,
|
any.transformers-base ==0.4.6,
|
||||||
transformers-base +orphaninstances,
|
transformers-base +orphaninstances,
|
||||||
any.transformers-compat ==0.7,
|
any.transformers-compat ==0.7.1,
|
||||||
transformers-compat -five +five-three -four +generic-deriving +mtl -three -two,
|
transformers-compat -five +five-three -four +generic-deriving +mtl -three -two,
|
||||||
any.unix ==2.7.2.2,
|
any.unix ==2.7.2.2,
|
||||||
any.unix-bytestring ==0.3.7.3,
|
any.unix-bytestring ==0.3.7.6,
|
||||||
any.unix-compat ==0.5.3,
|
any.unix-compat ==0.5.3,
|
||||||
unix-compat -old-time,
|
unix-compat -old-time,
|
||||||
any.unliftio-core ==0.2.0.1,
|
any.unliftio-core ==0.2.0.1,
|
||||||
any.unordered-containers ==0.2.14.0,
|
any.unordered-containers ==0.2.15.0,
|
||||||
unordered-containers -debug,
|
unordered-containers -debug,
|
||||||
any.uri-bytestring ==0.3.3.1,
|
any.uri-bytestring ==0.3.3.1,
|
||||||
uri-bytestring -lib-werror,
|
uri-bytestring -lib-werror,
|
||||||
@@ -204,10 +218,13 @@ constraints: any.Cabal ==3.2.1.0 || ==3.6.1.0,
|
|||||||
vector +boundschecks -internalchecks -unsafechecks -wall,
|
vector +boundschecks -internalchecks -unsafechecks -wall,
|
||||||
any.versions ==5.0.0,
|
any.versions ==5.0.0,
|
||||||
any.vty ==5.33,
|
any.vty ==5.33,
|
||||||
|
any.witherable ==0.4.2,
|
||||||
any.word-wrap ==0.5,
|
any.word-wrap ==0.5,
|
||||||
any.word8 ==0.1.3,
|
any.word8 ==0.1.3,
|
||||||
any.xor ==0.0.1.0,
|
any.xor ==0.0.1.0,
|
||||||
|
any.yaml-streamly ==0.12.0,
|
||||||
|
yaml-streamly +no-examples +no-exe,
|
||||||
any.zlib ==0.6.2.3,
|
any.zlib ==0.6.2.3,
|
||||||
zlib -bundled-c-zlib -non-blocking-ffi -pkg-config,
|
zlib -bundled-c-zlib -non-blocking-ffi -pkg-config,
|
||||||
any.zlib-bindings ==0.1.1.5
|
any.zlib-bindings ==0.1.1.5
|
||||||
index-state: hackage.haskell.org 2021-10-01T15:16:26Z
|
index-state: hackage.haskell.org 2021-11-12T11:11:19Z
|
||||||
|
|||||||
@@ -8,7 +8,9 @@ package ghcup
|
|||||||
tests: True
|
tests: True
|
||||||
flags: +tui
|
flags: +tui
|
||||||
|
|
||||||
constraints: http-io-streams -brotli
|
constraints: http-io-streams -brotli,
|
||||||
|
any.Cabal ==3.6.2.0,
|
||||||
|
any.aeson >= 2.0.1.0
|
||||||
|
|
||||||
package libarchive
|
package libarchive
|
||||||
flags: -system-libarchive
|
flags: -system-libarchive
|
||||||
@@ -19,6 +21,9 @@ package aeson-pretty
|
|||||||
package cabal-plan
|
package cabal-plan
|
||||||
flags: -exe
|
flags: -exe
|
||||||
|
|
||||||
|
package aeson
|
||||||
|
flags: +ordered-keymap
|
||||||
|
|
||||||
allow-newer: base, ghc-prim, template-haskell, language-c
|
allow-newer: base, ghc-prim, template-haskell, language-c
|
||||||
|
|
||||||
with-compiler: ghc-9.0.1
|
with-compiler: ghc-9.0.1
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
active-repositories: hackage.haskell.org:merge
|
active-repositories: hackage.haskell.org:merge
|
||||||
constraints: any.Cabal ==3.4.0.0 || ==3.6.1.0,
|
constraints: any.Cabal ==3.6.2.0,
|
||||||
Cabal -bundled-binary-generic,
|
Cabal -bundled-binary-generic,
|
||||||
any.HUnit ==1.6.2.0,
|
any.HUnit ==1.6.2.0,
|
||||||
any.HsOpenSSL ==0.11.7.2,
|
any.HsOpenSSL ==0.11.7.2,
|
||||||
HsOpenSSL -fast-bignum -homebrew-openssl -macports-openssl -use-pkg-config,
|
HsOpenSSL -fast-bignum -homebrew-openssl -macports-openssl -use-pkg-config,
|
||||||
any.HsYAML ==0.2.1.0,
|
any.OneTuple ==0.3.1,
|
||||||
HsYAML -exe,
|
|
||||||
any.HsYAML-aeson ==0.2.0.0,
|
|
||||||
any.QuickCheck ==2.14.2,
|
any.QuickCheck ==2.14.2,
|
||||||
QuickCheck -old-random +templatehaskell,
|
QuickCheck -old-random +templatehaskell,
|
||||||
any.StateVar ==1.2.2,
|
any.StateVar ==1.2.2,
|
||||||
any.aeson ==1.5.6.0,
|
any.abstract-deque ==0.3,
|
||||||
aeson -bytestring-builder -cffi -developer -fast,
|
abstract-deque -usecas,
|
||||||
any.aeson-pretty ==0.8.8,
|
any.aeson ==2.0.1.0,
|
||||||
|
aeson -bytestring-builder -cffi +ordered-keymap,
|
||||||
|
any.aeson-pretty ==0.8.9,
|
||||||
aeson-pretty +lib-only,
|
aeson-pretty +lib-only,
|
||||||
any.alex ==3.2.6,
|
any.alex ==3.2.6,
|
||||||
alex +small_base,
|
alex +small_base,
|
||||||
@@ -22,28 +22,30 @@ constraints: any.Cabal ==3.4.0.0 || ==3.6.1.0,
|
|||||||
ansi-wl-pprint -example,
|
ansi-wl-pprint -example,
|
||||||
any.array ==0.5.4.0,
|
any.array ==0.5.4.0,
|
||||||
any.assoc ==1.0.2,
|
any.assoc ==1.0.2,
|
||||||
any.async ==2.2.3,
|
any.async ==2.2.4,
|
||||||
async -bench,
|
async -bench,
|
||||||
|
any.atomic-primops ==0.8.4,
|
||||||
|
atomic-primops -debug,
|
||||||
any.attoparsec ==0.13.2.5,
|
any.attoparsec ==0.13.2.5,
|
||||||
attoparsec -developer,
|
attoparsec -developer,
|
||||||
any.base ==4.15.0.0,
|
any.base ==4.15.0.0,
|
||||||
any.base-compat ==0.12.0,
|
any.base-compat ==0.12.1,
|
||||||
any.base-compat-batteries ==0.12.0,
|
any.base-compat-batteries ==0.12.1,
|
||||||
any.base-orphans ==0.8.5,
|
any.base-orphans ==0.8.6,
|
||||||
any.base16-bytestring ==1.0.1.0,
|
any.base16-bytestring ==1.0.2.0,
|
||||||
any.base64-bytestring ==1.1.0.0,
|
any.base64-bytestring ==1.1.0.0,
|
||||||
any.bifunctors ==5.5.11,
|
any.bifunctors ==5.5.11,
|
||||||
bifunctors +semigroups +tagged,
|
bifunctors +semigroups +tagged,
|
||||||
any.binary ==0.8.8.0,
|
any.binary ==0.8.8.0,
|
||||||
any.blaze-builder ==0.4.2.1,
|
any.blaze-builder ==0.4.2.2,
|
||||||
any.brick ==0.64.1,
|
any.brick ==0.64.2,
|
||||||
brick -demos,
|
brick -demos,
|
||||||
any.bytestring ==0.10.12.1,
|
any.bytestring ==0.10.12.1,
|
||||||
any.bz2 ==1.0.1.0,
|
any.bz2 ==1.0.1.0,
|
||||||
bz2 -cross +with-bzlib,
|
bz2 -cross +with-bzlib,
|
||||||
any.c2hs ==0.28.8,
|
any.c2hs ==0.28.8,
|
||||||
c2hs +base3 -regression,
|
c2hs +base3 -regression,
|
||||||
any.cabal-plan ==0.7.2.0,
|
any.cabal-plan ==0.7.2.1,
|
||||||
cabal-plan -_ -exe -license-report,
|
cabal-plan -_ -exe -license-report,
|
||||||
any.call-stack ==0.4.0,
|
any.call-stack ==0.4.0,
|
||||||
any.case-insensitive ==1.2.1.0,
|
any.case-insensitive ==1.2.1.0,
|
||||||
@@ -66,7 +68,7 @@ constraints: any.Cabal ==3.4.0.0 || ==3.6.1.0,
|
|||||||
any.cpphs ==1.20.9.1,
|
any.cpphs ==1.20.9.1,
|
||||||
cpphs -old-locale,
|
cpphs -old-locale,
|
||||||
any.cryptohash-sha1 ==0.11.100.1,
|
any.cryptohash-sha1 ==0.11.100.1,
|
||||||
any.cryptohash-sha256 ==0.11.102.0,
|
any.cryptohash-sha256 ==0.11.102.1,
|
||||||
cryptohash-sha256 -exe +use-cbits,
|
cryptohash-sha256 -exe +use-cbits,
|
||||||
any.data-clist ==0.1.2.3,
|
any.data-clist ==0.1.2.3,
|
||||||
any.data-fix ==0.3.2,
|
any.data-fix ==0.3.2,
|
||||||
@@ -80,18 +82,20 @@ constraints: any.Cabal ==3.4.0.0 || ==3.6.1.0,
|
|||||||
any.exceptions ==0.10.4,
|
any.exceptions ==0.10.4,
|
||||||
any.filepath ==1.4.2.1,
|
any.filepath ==1.4.2.1,
|
||||||
any.free ==5.1.7,
|
any.free ==5.1.7,
|
||||||
|
any.fusion-plugin-types ==0.1.0,
|
||||||
any.generic-arbitrary ==0.1.0,
|
any.generic-arbitrary ==0.1.0,
|
||||||
any.ghc-bignum ==1.0,
|
any.ghc-bignum ==1.0,
|
||||||
any.ghc-boot-th ==9.0.1,
|
any.ghc-boot-th ==9.0.1,
|
||||||
any.ghc-byteorder ==4.11.0.0.10,
|
any.ghc-byteorder ==4.11.0.0.10,
|
||||||
any.ghc-prim ==0.7.0,
|
any.ghc-prim ==0.7.0,
|
||||||
any.happy ==1.20.0,
|
any.happy ==1.20.0,
|
||||||
any.hashable ==1.3.3.0,
|
any.hashable ==1.3.5.0,
|
||||||
hashable +integer-gmp -random-initial-seed,
|
hashable +integer-gmp -random-initial-seed,
|
||||||
any.haskus-utils-data ==1.4,
|
any.haskus-utils-data ==1.4,
|
||||||
any.haskus-utils-types ==1.5.1,
|
any.haskus-utils-types ==1.5.1,
|
||||||
any.haskus-utils-variant ==3.1,
|
any.haskus-utils-variant ==3.2.1,
|
||||||
any.hsc2hs ==0.68.7,
|
any.heaps ==0.4,
|
||||||
|
any.hsc2hs ==0.68.8,
|
||||||
hsc2hs -in-ghc-tree,
|
hsc2hs -in-ghc-tree,
|
||||||
any.hspec ==2.7.10,
|
any.hspec ==2.7.10,
|
||||||
any.hspec-core ==2.7.10,
|
any.hspec-core ==2.7.10,
|
||||||
@@ -101,24 +105,28 @@ constraints: any.Cabal ==3.4.0.0 || ==3.6.1.0,
|
|||||||
any.http-io-streams ==0.1.6.0,
|
any.http-io-streams ==0.1.6.0,
|
||||||
http-io-streams -brotli +fast-xor,
|
http-io-streams -brotli +fast-xor,
|
||||||
any.indexed-profunctors ==0.1.1,
|
any.indexed-profunctors ==0.1.1,
|
||||||
any.indexed-traversable ==0.1.1,
|
any.indexed-traversable ==0.1.2,
|
||||||
any.indexed-traversable-instances ==0.1,
|
any.indexed-traversable-instances ==0.1.1,
|
||||||
any.integer-logarithms ==1.0.3.1,
|
any.integer-logarithms ==1.0.3.1,
|
||||||
integer-logarithms -check-bounds +integer-gmp,
|
integer-logarithms -check-bounds +integer-gmp,
|
||||||
any.io-streams ==1.5.2.1,
|
any.io-streams ==1.5.2.1,
|
||||||
io-streams +network -nointeractivetests +zlib,
|
io-streams +network -nointeractivetests +zlib,
|
||||||
any.language-c ==0.9.0.1,
|
any.language-c ==0.9.0.1,
|
||||||
language-c -allwarnings +iecfpextension +usebytestrings,
|
language-c -allwarnings +iecfpextension +usebytestrings,
|
||||||
any.libarchive ==3.0.3.0,
|
any.libarchive ==3.0.3.1,
|
||||||
libarchive -cross -low-memory -system-libarchive,
|
libarchive -cross -low-memory -system-libarchive,
|
||||||
|
any.libyaml-streamly ==0.2.0,
|
||||||
|
libyaml-streamly -no-unicode -system-libyaml,
|
||||||
|
any.lockfree-queue ==0.2.3.1,
|
||||||
any.lzma-static ==5.2.5.4,
|
any.lzma-static ==5.2.5.4,
|
||||||
any.megaparsec ==9.0.1,
|
any.megaparsec ==9.0.1,
|
||||||
megaparsec -dev,
|
megaparsec -dev,
|
||||||
any.microlens ==0.4.12.0,
|
any.microlens ==0.4.12.0,
|
||||||
any.microlens-mtl ==0.2.0.1,
|
any.microlens-mtl ==0.2.0.1,
|
||||||
any.microlens-th ==0.4.3.10,
|
any.microlens-th ==0.4.3.10,
|
||||||
|
any.monad-control ==1.0.3.1,
|
||||||
any.mtl ==2.2.2,
|
any.mtl ==2.2.2,
|
||||||
any.network ==3.1.2.2,
|
any.network ==3.1.2.5,
|
||||||
network -devel,
|
network -devel,
|
||||||
any.network-uri ==2.6.4.1,
|
any.network-uri ==2.6.4.1,
|
||||||
any.openssl-streams ==1.2.3.0,
|
any.openssl-streams ==1.2.3.0,
|
||||||
@@ -129,7 +137,7 @@ constraints: any.Cabal ==3.4.0.0 || ==3.6.1.0,
|
|||||||
any.optics-th ==0.4,
|
any.optics-th ==0.4,
|
||||||
any.optparse-applicative ==0.16.1.0,
|
any.optparse-applicative ==0.16.1.0,
|
||||||
optparse-applicative +process,
|
optparse-applicative +process,
|
||||||
any.os-release ==1.0.2,
|
any.os-release ==1.0.2.1,
|
||||||
os-release -devel,
|
os-release -devel,
|
||||||
any.parallel ==3.2.2.0,
|
any.parallel ==3.2.2.0,
|
||||||
any.parsec ==3.1.14.0,
|
any.parsec ==3.1.14.0,
|
||||||
@@ -138,30 +146,36 @@ constraints: any.Cabal ==3.4.0.0 || ==3.6.1.0,
|
|||||||
any.polyparse ==1.13,
|
any.polyparse ==1.13,
|
||||||
any.pretty ==1.1.3.6,
|
any.pretty ==1.1.3.6,
|
||||||
any.pretty-terminal ==0.1.0.0,
|
any.pretty-terminal ==0.1.0.0,
|
||||||
any.primitive ==0.7.2.0,
|
any.primitive ==0.7.3.0,
|
||||||
any.process ==1.6.11.0,
|
any.process ==1.6.11.0,
|
||||||
any.profunctors ==5.6.2,
|
any.profunctors ==5.6.2,
|
||||||
any.quickcheck-arbitrary-adt ==0.3.1.0,
|
any.quickcheck-arbitrary-adt ==0.3.1.0,
|
||||||
any.quickcheck-io ==0.2.0,
|
any.quickcheck-io ==0.2.0,
|
||||||
any.random ==1.2.1,
|
any.random ==1.2.1,
|
||||||
any.recursion-schemes ==5.2.2.1,
|
any.recursion-schemes ==5.2.2.2,
|
||||||
recursion-schemes +template-haskell,
|
recursion-schemes +template-haskell,
|
||||||
any.regex-base ==0.94.0.1,
|
any.regex-base ==0.94.0.1,
|
||||||
any.regex-posix ==0.96.0.1,
|
any.regex-posix ==0.96.0.1,
|
||||||
regex-posix -_regex-posix-clib,
|
regex-posix -_regex-posix-clib,
|
||||||
any.resourcet ==1.2.4.3,
|
any.resourcet ==1.2.4.3,
|
||||||
|
any.retry ==0.8.1.2,
|
||||||
|
retry -lib-werror,
|
||||||
any.rts ==1.0,
|
any.rts ==1.0,
|
||||||
any.safe ==0.3.19,
|
any.safe ==0.3.19,
|
||||||
any.safe-exceptions ==0.1.7.2,
|
any.safe-exceptions ==0.1.7.2,
|
||||||
any.scientific ==0.3.7.0,
|
any.scientific ==0.3.7.0,
|
||||||
scientific -bytestring-builder -integer-simple,
|
scientific -bytestring-builder -integer-simple,
|
||||||
any.semigroupoids ==5.3.5,
|
any.semialign ==1.2.0.1,
|
||||||
|
semialign +semigroupoids,
|
||||||
|
any.semigroupoids ==5.3.6,
|
||||||
semigroupoids +comonad +containers +contravariant +distributive +tagged +unordered-containers,
|
semigroupoids +comonad +containers +contravariant +distributive +tagged +unordered-containers,
|
||||||
any.setenv ==0.1.1.3,
|
any.setenv ==0.1.1.3,
|
||||||
any.split ==0.2.3.4,
|
any.split ==0.2.3.4,
|
||||||
any.splitmix ==0.1.0.3,
|
any.splitmix ==0.1.0.4,
|
||||||
splitmix -optimised-mixer,
|
splitmix -optimised-mixer,
|
||||||
any.stm ==2.5.0.0,
|
any.stm ==2.5.0.0,
|
||||||
|
any.streamly ==0.8.0,
|
||||||
|
streamly -debug -dev -fusion-plugin -has-llvm -inspection -no-fusion +opt -streamk -use-c-malloc,
|
||||||
any.strict ==0.4.0.1,
|
any.strict ==0.4.0.1,
|
||||||
strict +assoc,
|
strict +assoc,
|
||||||
any.strict-base ==0.4.0.0,
|
any.strict-base ==0.4.0.0,
|
||||||
@@ -187,14 +201,14 @@ constraints: any.Cabal ==3.4.0.0 || ==3.6.1.0,
|
|||||||
any.transformers ==0.5.6.2,
|
any.transformers ==0.5.6.2,
|
||||||
any.transformers-base ==0.4.6,
|
any.transformers-base ==0.4.6,
|
||||||
transformers-base +orphaninstances,
|
transformers-base +orphaninstances,
|
||||||
any.transformers-compat ==0.7,
|
any.transformers-compat ==0.7.1,
|
||||||
transformers-compat -five +five-three -four +generic-deriving +mtl -three -two,
|
transformers-compat -five +five-three -four +generic-deriving +mtl -three -two,
|
||||||
any.unix ==2.7.2.2,
|
any.unix ==2.7.2.2,
|
||||||
any.unix-bytestring ==0.3.7.3,
|
any.unix-bytestring ==0.3.7.6,
|
||||||
any.unix-compat ==0.5.3,
|
any.unix-compat ==0.5.3,
|
||||||
unix-compat -old-time,
|
unix-compat -old-time,
|
||||||
any.unliftio-core ==0.2.0.1,
|
any.unliftio-core ==0.2.0.1,
|
||||||
any.unordered-containers ==0.2.14.0,
|
any.unordered-containers ==0.2.15.0,
|
||||||
unordered-containers -debug,
|
unordered-containers -debug,
|
||||||
any.uri-bytestring ==0.3.3.1,
|
any.uri-bytestring ==0.3.3.1,
|
||||||
uri-bytestring -lib-werror,
|
uri-bytestring -lib-werror,
|
||||||
@@ -204,10 +218,13 @@ constraints: any.Cabal ==3.4.0.0 || ==3.6.1.0,
|
|||||||
vector +boundschecks -internalchecks -unsafechecks -wall,
|
vector +boundschecks -internalchecks -unsafechecks -wall,
|
||||||
any.versions ==5.0.0,
|
any.versions ==5.0.0,
|
||||||
any.vty ==5.33,
|
any.vty ==5.33,
|
||||||
|
any.witherable ==0.4.2,
|
||||||
any.word-wrap ==0.5,
|
any.word-wrap ==0.5,
|
||||||
any.word8 ==0.1.3,
|
any.word8 ==0.1.3,
|
||||||
any.xor ==0.0.1.0,
|
any.xor ==0.0.1.0,
|
||||||
|
any.yaml-streamly ==0.12.0,
|
||||||
|
yaml-streamly +no-examples +no-exe,
|
||||||
any.zlib ==0.6.2.3,
|
any.zlib ==0.6.2.3,
|
||||||
zlib -bundled-c-zlib -non-blocking-ffi -pkg-config,
|
zlib -bundled-c-zlib -non-blocking-ffi -pkg-config,
|
||||||
any.zlib-bindings ==0.1.1.5
|
any.zlib-bindings ==0.1.1.5
|
||||||
index-state: hackage.haskell.org 2021-10-01T15:16:26Z
|
index-state: hackage.haskell.org 2021-11-12T11:11:19Z
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ package ghcup
|
|||||||
flags: +tui
|
flags: +tui
|
||||||
|
|
||||||
constraints: http-io-streams -brotli,
|
constraints: http-io-streams -brotli,
|
||||||
any.Cabal ==3.4.1.0 || ==3.6.2.0,
|
any.Cabal ==3.6.2.0,
|
||||||
any.aeson >= 2.0.1.0
|
any.aeson >= 2.0.1.0
|
||||||
|
|
||||||
package libarchive
|
package libarchive
|
||||||
|
|||||||
@@ -36,6 +36,10 @@ key-bindings:
|
|||||||
show-all-tools:
|
show-all-tools:
|
||||||
KChar: 't'
|
KChar: 't'
|
||||||
|
|
||||||
|
# The caching for the metadata files containing download info, depending on last access time
|
||||||
|
# of the file. These usually are in '~/.ghcup/cache/ghcup-<ver>.yaml'.
|
||||||
|
meta-cache: 300 # in seconds
|
||||||
|
|
||||||
# Where to get GHC/cabal/hls download info/versions from. For more detailed explanation
|
# Where to get GHC/cabal/hls download info/versions from. For more detailed explanation
|
||||||
# check the 'URLSource' type in the code.
|
# check the 'URLSource' type in the code.
|
||||||
url-source:
|
url-source:
|
||||||
|
|||||||
16
docs/dev.md
16
docs/dev.md
@@ -95,21 +95,19 @@ Every subcommand now lives in its own module under [GHCup.OptParse.MyCommand](ht
|
|||||||
|
|
||||||
3. Add ChangeLog entry
|
3. Add ChangeLog entry
|
||||||
|
|
||||||
4. Add/fix downloads in `ghcup-<ver>.yaml` ([ghcup-metadata repo](https://github.com/haskell/ghcup-metadata)), then verify with `ghcup-gen check -f ghcup-<ver>.yaml` and possibly (example only) `ghcup-gen check-tarballs -f ghcup-<ver>.yaml -u 'ghc-8.10.7'`. Generally, new GHC/cabal/stack/hls versions are only added to the latest yaml file. New GHCup versions are added to all (great care must be taken here to not break the parser... e.g. ARM platforms don't parse in all older formats).
|
4. Commit and git push with tag. Wait for tests to succeed and release artifacts to build.
|
||||||
|
|
||||||
5. Commit and git push with tag. Wait for tests to succeed and release artifacts to build.
|
5. Download release artifacts and upload them `downloads.haskell.org/~ghcup` along with checksum files (`sha256sum --tag * > SHA256SUMS && gpg --detach-sign -u <your-email> SHA256SUMS`)
|
||||||
|
|
||||||
6. Download release artifacts and upload them `downloads.haskell.org/~ghcup` along with checksum files (`sha256sum --tag * > SHA256SUMS && gpg --detach-sign -u <your-email> SHA256SUMS`)
|
6. Add ghcup release artifacts to ALL yaml files, see [ghcup-metadata repo](https://github.com/haskell/ghcup-metadata)
|
||||||
|
|
||||||
7. Add ghcup release artifacts to ALL yaml files (see point 4.)
|
7. Upload the final `ghcup-<ver>.yaml` (and a detached GPG sig of it) to `webhost.haskell.org/ghcup/data/` (for yaml versions <= 0.0.6) as well as [https://github.com/haskell/ghcup-metadata](https://github.com/haskell/ghcup-metadata) (for all versions).
|
||||||
|
|
||||||
8. Upload the final `ghcup-<ver>.yaml` (and a detached GPG sig of it) to `webhost.haskell.org/ghcup/data/` (for yaml versions <= 0.0.6) as well as [https://github.com/haskell/ghcup-metadata](https://github.com/haskell/ghcup-metadata) (for all versions).
|
8. Upload `bootstrap-haskell` and `bootstrap-haskell.ps1` to `webhost.haskell.org/ghcup/sh/`
|
||||||
|
|
||||||
9. Upload `bootstrap-haskell` and `bootstrap-haskell.ps1` to `webhost.haskell.org/ghcup/sh/`
|
9. Update the top-level ghcup symlinks at `downloads.haskell.org/~ghcup`
|
||||||
|
|
||||||
10. Update the top-level ghcup symlinks at `downloads.haskell.org/~ghcup`
|
10. Post on reddit/discourse/etc. and collect rewards
|
||||||
|
|
||||||
11. Post on reddit/discourse/etc. and collect rewards
|
|
||||||
|
|
||||||
# Documentation
|
# Documentation
|
||||||
|
|
||||||
|
|||||||
@@ -53,6 +53,25 @@ as e.g. `/etc/bash_completion.d/ghcup` (depending on distro)
|
|||||||
and make sure your bashrc sources the startup script
|
and make sure your bashrc sources the startup script
|
||||||
(`/usr/share/bash-completion/bash_completion` on some distros).
|
(`/usr/share/bash-completion/bash_completion` on some distros).
|
||||||
|
|
||||||
|
## Caching
|
||||||
|
|
||||||
|
GHCup has a few caching mechanisms to avoid redownloads. All cached files end up in `~/.ghcup/cache` by default.
|
||||||
|
|
||||||
|
### Downloads cache
|
||||||
|
|
||||||
|
Downloaded tarballs (such as GHC, cabal, etc.) are not cached by default unless you pass `ghcup --cache` or set caching
|
||||||
|
in your [config](#configuration) via `ghcup config set cache true`.
|
||||||
|
|
||||||
|
### Metadata cache
|
||||||
|
|
||||||
|
The metadata files (also see [github.com/haskell/ghcup-metadata](https://github.com/haskell/ghcup-metadata))
|
||||||
|
have a 5 minutes cache per default depending on the last access time of the file. That means if you run
|
||||||
|
`ghcup list` 10 times in a row, only the first time will trigger a download attempt.
|
||||||
|
|
||||||
|
### Clearing the cache
|
||||||
|
|
||||||
|
If you experience problems, consider clearing the cache via `ghcup gc --cache`.
|
||||||
|
|
||||||
## Compiling GHC from source
|
## Compiling GHC from source
|
||||||
|
|
||||||
Compiling from source is supported for both source tarballs and arbitrary git refs. See `ghcup compile ghc --help`
|
Compiling from source is supported for both source tarballs and arbitrary git refs. See `ghcup compile ghc --help`
|
||||||
|
|||||||
68
ghcup.cabal
68
ghcup.cabal
@@ -1,6 +1,6 @@
|
|||||||
cabal-version: 3.0
|
cabal-version: 3.0
|
||||||
name: ghcup
|
name: ghcup
|
||||||
version: 0.1.17.2
|
version: 0.1.17.4
|
||||||
license: LGPL-3.0-only
|
license: LGPL-3.0-only
|
||||||
license-file: LICENSE
|
license-file: LICENSE
|
||||||
copyright: Julian Ospald 2020
|
copyright: Julian Ospald 2020
|
||||||
@@ -18,9 +18,6 @@ build-type: Simple
|
|||||||
extra-doc-files:
|
extra-doc-files:
|
||||||
CHANGELOG.md
|
CHANGELOG.md
|
||||||
data/config.yaml
|
data/config.yaml
|
||||||
data/metadata/ghcup-0.0.4.yaml
|
|
||||||
data/metadata/ghcup-0.0.5.yaml
|
|
||||||
data/metadata/ghcup-0.0.6.yaml
|
|
||||||
README.md
|
README.md
|
||||||
|
|
||||||
extra-source-files:
|
extra-source-files:
|
||||||
@@ -46,6 +43,11 @@ flag internal-downloader
|
|||||||
default: False
|
default: False
|
||||||
manual: True
|
manual: True
|
||||||
|
|
||||||
|
flag no-exe
|
||||||
|
description: Don't build any executables
|
||||||
|
default: False
|
||||||
|
manual: True
|
||||||
|
|
||||||
library
|
library
|
||||||
exposed-modules:
|
exposed-modules:
|
||||||
GHCup
|
GHCup
|
||||||
@@ -94,7 +96,7 @@ library
|
|||||||
build-depends:
|
build-depends:
|
||||||
, aeson >=1.4
|
, aeson >=1.4
|
||||||
, async >=0.8 && <2.3
|
, async >=0.8 && <2.3
|
||||||
, base >=4.13 && <5
|
, base >=4.12 && <5
|
||||||
, base16-bytestring >=0.1.1.6 && <1.1
|
, base16-bytestring >=0.1.1.6 && <1.1
|
||||||
, binary ^>=0.8.6.0
|
, binary ^>=0.8.6.0
|
||||||
, bytestring ^>=0.10
|
, bytestring ^>=0.10
|
||||||
@@ -108,7 +110,7 @@ library
|
|||||||
, disk-free-space ^>=0.1.0.1
|
, disk-free-space ^>=0.1.0.1
|
||||||
, filepath ^>=1.4.2.1
|
, filepath ^>=1.4.2.1
|
||||||
, haskus-utils-types ^>=1.5
|
, haskus-utils-types ^>=1.5
|
||||||
, haskus-utils-variant >=3.0 && <3.2
|
, haskus-utils-variant ^>=3.2.1
|
||||||
, libarchive ^>=3.0.3.0
|
, libarchive ^>=3.0.3.0
|
||||||
, lzma-static ^>=5.2.5.3
|
, lzma-static ^>=5.2.5.3
|
||||||
, megaparsec >=8.0.0 && <9.1
|
, megaparsec >=8.0.0 && <9.1
|
||||||
@@ -217,14 +219,15 @@ executable ghcup
|
|||||||
, aeson >=1.4
|
, aeson >=1.4
|
||||||
, aeson-pretty ^>=0.8.8
|
, aeson-pretty ^>=0.8.8
|
||||||
, async ^>=2.2.3
|
, async ^>=2.2.3
|
||||||
, base >=4.13 && <5
|
, base >=4.12 && <5
|
||||||
, bytestring ^>=0.10
|
, bytestring ^>=0.10
|
||||||
, cabal-plan ^>=0.7.2
|
, cabal-plan ^>=0.7.2
|
||||||
, containers ^>=0.6
|
, containers ^>=0.6
|
||||||
, deepseq ^>=1.4
|
, deepseq ^>=1.4
|
||||||
|
, directory ^>=1.3.6.0
|
||||||
, filepath ^>=1.4.2.1
|
, filepath ^>=1.4.2.1
|
||||||
, ghcup
|
, ghcup
|
||||||
, haskus-utils-variant >=3.0 && <3.2
|
, haskus-utils-variant ^>=3.2.1
|
||||||
, libarchive ^>=3.0.3.0
|
, libarchive ^>=3.0.3.0
|
||||||
, megaparsec >=8.0.0 && <9.1
|
, megaparsec >=8.0.0 && <9.1
|
||||||
, mtl ^>=2.2
|
, mtl ^>=2.2
|
||||||
@@ -250,56 +253,15 @@ executable ghcup
|
|||||||
build-depends:
|
build-depends:
|
||||||
, brick ^>=0.64
|
, brick ^>=0.64
|
||||||
, transformers ^>=0.5
|
, transformers ^>=0.5
|
||||||
|
, unix ^>=2.7
|
||||||
, vector ^>=0.12
|
, vector ^>=0.12
|
||||||
, vty >=5.28.2 && <5.34
|
, vty >=5.28.2 && <5.34
|
||||||
|
|
||||||
if os(windows)
|
if os(windows)
|
||||||
cpp-options: -DIS_WINDOWS
|
cpp-options: -DIS_WINDOWS
|
||||||
|
|
||||||
executable ghcup-gen
|
if flag(no-exe)
|
||||||
main-is: Main.hs
|
buildable: False
|
||||||
hs-source-dirs: app/ghcup-gen
|
|
||||||
other-modules: Validate
|
|
||||||
default-language: Haskell2010
|
|
||||||
default-extensions:
|
|
||||||
DeriveGeneric
|
|
||||||
LambdaCase
|
|
||||||
MultiWayIf
|
|
||||||
NamedFieldPuns
|
|
||||||
PackageImports
|
|
||||||
QuasiQuotes
|
|
||||||
RecordWildCards
|
|
||||||
ScopedTypeVariables
|
|
||||||
StrictData
|
|
||||||
TupleSections
|
|
||||||
TypeApplications
|
|
||||||
TypeFamilies
|
|
||||||
ViewPatterns
|
|
||||||
|
|
||||||
ghc-options:
|
|
||||||
-Wall -fwarn-tabs -fwarn-incomplete-uni-patterns
|
|
||||||
-fwarn-incomplete-record-updates -threaded
|
|
||||||
|
|
||||||
build-depends:
|
|
||||||
, base >=4.13 && <5
|
|
||||||
, bytestring ^>=0.10
|
|
||||||
, containers ^>=0.6
|
|
||||||
, filepath ^>=1.4.2.1
|
|
||||||
, ghcup
|
|
||||||
, haskus-utils-variant >=3.0 && <3.2
|
|
||||||
, libarchive ^>=3.0.3.0
|
|
||||||
, mtl ^>=2.2
|
|
||||||
, optics ^>=0.4
|
|
||||||
, optparse-applicative >=0.15.1.0 && <0.17
|
|
||||||
, pretty ^>=1.1.3.1
|
|
||||||
, pretty-terminal ^>=0.1.0.0
|
|
||||||
, regex-posix ^>=0.96
|
|
||||||
, resourcet ^>=1.2.2
|
|
||||||
, safe-exceptions ^>=0.1
|
|
||||||
, text ^>=1.2.4.0
|
|
||||||
, transformers ^>=0.5
|
|
||||||
, versions >=4.0.1 && <5.1
|
|
||||||
, yaml-streamly ^>=0.12.0
|
|
||||||
|
|
||||||
test-suite ghcup-test
|
test-suite ghcup-test
|
||||||
type: exitcode-stdio-1.0
|
type: exitcode-stdio-1.0
|
||||||
@@ -325,7 +287,7 @@ test-suite ghcup-test
|
|||||||
-fwarn-incomplete-record-updates
|
-fwarn-incomplete-record-updates
|
||||||
|
|
||||||
build-depends:
|
build-depends:
|
||||||
, base >=4.13 && <5
|
, base >=4.12 && <5
|
||||||
, bytestring ^>=0.10
|
, bytestring ^>=0.10
|
||||||
, containers ^>=0.6
|
, containers ^>=0.6
|
||||||
, generic-arbitrary ^>=0.1.0
|
, generic-arbitrary ^>=0.1.0
|
||||||
|
|||||||
2
hie.yaml
2
hie.yaml
@@ -4,7 +4,5 @@ cradle:
|
|||||||
path: ./lib
|
path: ./lib
|
||||||
- component: "ghcup:exe:ghcup"
|
- component: "ghcup:exe:ghcup"
|
||||||
path: ./app/ghcup
|
path: ./app/ghcup
|
||||||
- component: "ghcup:exe:ghcup-gen"
|
|
||||||
path: "./app/ghcup-gen"
|
|
||||||
- component: "ghcup:test:ghcup-test"
|
- component: "ghcup:test:ghcup-test"
|
||||||
path: ./test
|
path: ./test
|
||||||
|
|||||||
95
lib/GHCup.hs
95
lib/GHCup.hs
@@ -62,7 +62,7 @@ import Data.String ( fromString )
|
|||||||
import Data.Text ( Text )
|
import Data.Text ( Text )
|
||||||
import Data.Time.Clock
|
import Data.Time.Clock
|
||||||
import Data.Time.Format.ISO8601
|
import Data.Time.Format.ISO8601
|
||||||
import Data.Versions
|
import Data.Versions hiding ( patch )
|
||||||
import Distribution.Types.Version hiding ( Version )
|
import Distribution.Types.Version hiding ( Version )
|
||||||
import Distribution.Types.PackageId
|
import Distribution.Types.PackageId
|
||||||
import Distribution.Types.PackageDescription
|
import Distribution.Types.PackageDescription
|
||||||
@@ -84,6 +84,7 @@ import System.IO.Error
|
|||||||
import System.IO.Temp
|
import System.IO.Temp
|
||||||
import Text.PrettyPrint.HughesPJClass ( prettyShow )
|
import Text.PrettyPrint.HughesPJClass ( prettyShow )
|
||||||
import Text.Regex.Posix
|
import Text.Regex.Posix
|
||||||
|
import URI.ByteString
|
||||||
|
|
||||||
import qualified Crypto.Hash.SHA256 as SHA256
|
import qualified Crypto.Hash.SHA256 as SHA256
|
||||||
import qualified Data.List.NonEmpty as NE
|
import qualified Data.List.NonEmpty as NE
|
||||||
@@ -750,9 +751,10 @@ compileHLS :: ( MonadMask m
|
|||||||
-> Maybe Int
|
-> Maybe Int
|
||||||
-> Maybe Version
|
-> Maybe Version
|
||||||
-> Maybe FilePath
|
-> Maybe FilePath
|
||||||
-> Maybe FilePath
|
-> Maybe (Either FilePath URI)
|
||||||
-> Maybe FilePath
|
-> Maybe URI
|
||||||
-> Maybe FilePath
|
-> Maybe (Either FilePath [URI]) -- ^ patches
|
||||||
|
-> [Text] -- ^ additional args to cabal install
|
||||||
-> Excepts '[ NoDownload
|
-> Excepts '[ NoDownload
|
||||||
, GPGError
|
, GPGError
|
||||||
, DownloadFailed
|
, DownloadFailed
|
||||||
@@ -763,11 +765,12 @@ compileHLS :: ( MonadMask m
|
|||||||
, BuildFailed
|
, BuildFailed
|
||||||
, NotInstalled
|
, NotInstalled
|
||||||
] m Version
|
] m Version
|
||||||
compileHLS targetHLS ghcs jobs ov isolateDir cabalProject cabalProjectLocal patchdir = do
|
compileHLS targetHLS ghcs jobs ov isolateDir cabalProject cabalProjectLocal patches cabalArgs = do
|
||||||
PlatformRequest { .. } <- lift getPlatformReq
|
PlatformRequest { .. } <- lift getPlatformReq
|
||||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||||
Dirs { .. } <- lift getDirs
|
Dirs { .. } <- lift getDirs
|
||||||
|
|
||||||
|
|
||||||
(workdir, tver) <- case targetHLS of
|
(workdir, tver) <- case targetHLS of
|
||||||
-- unpack from version tarball
|
-- unpack from version tarball
|
||||||
Left tver -> do
|
Left tver -> do
|
||||||
@@ -834,48 +837,51 @@ compileHLS targetHLS ghcs jobs ov isolateDir cabalProject cabalProjectLocal patc
|
|||||||
liftE $ runBuildAction
|
liftE $ runBuildAction
|
||||||
workdir
|
workdir
|
||||||
Nothing
|
Nothing
|
||||||
(reThrowAll @_ @'[PatchFailed, ProcessError, FileAlreadyExistsError, CopyError] @'[BuildFailed] (BuildFailed workdir) $ do
|
(reThrowAll @_ @'[GPGError, DownloadFailed, DigestError, PatchFailed, ProcessError, FileAlreadyExistsError, CopyError] @'[BuildFailed] (BuildFailed workdir) $ do
|
||||||
let installDir = workdir </> "out"
|
let installDir = workdir </> "out"
|
||||||
liftIO $ createDirRecursive' installDir
|
liftIO $ createDirRecursive' installDir
|
||||||
|
|
||||||
-- apply patches
|
-- apply patches
|
||||||
forM_ patchdir (\dir -> liftE $ applyPatches dir workdir)
|
liftE $ applyAnyPatch patches workdir
|
||||||
|
|
||||||
-- set up project files
|
-- set up project files
|
||||||
cp <- case cabalProject of
|
cp <- case cabalProject of
|
||||||
Just cp
|
Just (Left cp)
|
||||||
| isAbsolute cp -> do
|
| isAbsolute cp -> do
|
||||||
copyFileE cp (workdir </> "cabal.project")
|
copyFileE cp (workdir </> "cabal.project")
|
||||||
pure "cabal.project"
|
pure "cabal.project"
|
||||||
| otherwise -> pure (takeFileName cp)
|
| otherwise -> pure (takeFileName cp)
|
||||||
|
Just (Right uri) -> do
|
||||||
|
tmpUnpack <- lift withGHCupTmpDir
|
||||||
|
cp <- liftE $ download uri Nothing Nothing tmpUnpack (Just "cabal.project") False
|
||||||
|
copyFileE cp (workdir </> "cabal.project")
|
||||||
|
pure "cabal.project"
|
||||||
Nothing -> pure "cabal.project"
|
Nothing -> pure "cabal.project"
|
||||||
forM_ cabalProjectLocal $ \cpl -> copyFileE cpl (workdir </> cp <.> "local")
|
forM_ cabalProjectLocal $ \uri -> do
|
||||||
|
tmpUnpack <- lift withGHCupTmpDir
|
||||||
let targets = ["exe:haskell-language-server", "exe:haskell-language-server-wrapper"]
|
cpl <- liftE $ download uri Nothing Nothing tmpUnpack (Just (cp <.> "local")) False
|
||||||
|
copyFileE cpl (workdir </> cp <.> "local")
|
||||||
artifacts <- forM (sort ghcs) $ \ghc -> do
|
artifacts <- forM (sort ghcs) $ \ghc -> do
|
||||||
let ghcInstallDir = installDir </> T.unpack (prettyVer ghc)
|
let ghcInstallDir = installDir </> T.unpack (prettyVer ghc)
|
||||||
liftIO $ createDirRecursive' ghcInstallDir
|
liftIO $ createDirRecursive' installDir
|
||||||
lift $ logInfo $ "Building HLS " <> prettyVer installVer <> " for GHC version " <> prettyVer ghc
|
lift $ logInfo $ "Building HLS " <> prettyVer installVer <> " for GHC version " <> prettyVer ghc
|
||||||
liftE $ lEM @_ @'[ProcessError] $
|
liftE $ lEM @_ @'[ProcessError] $
|
||||||
execLogged "cabal" ( [ "v2-build"
|
execLogged "cabal" ( [ "v2-install"
|
||||||
, "-w"
|
, "-w"
|
||||||
, "ghc-" <> T.unpack (prettyVer ghc)
|
, "ghc-" <> T.unpack (prettyVer ghc)
|
||||||
|
, "--install-method=copy"
|
||||||
] ++
|
] ++
|
||||||
maybe [] (\j -> ["--jobs=" <> show j]) jobs ++
|
maybe [] (\j -> ["--jobs=" <> show j]) jobs ++
|
||||||
[ "--project-file=" <> cp
|
[ "--overwrite-policy=always"
|
||||||
] ++ targets
|
, "--disable-profiling"
|
||||||
|
, "--disable-tests"
|
||||||
|
, "--installdir=" <> ghcInstallDir
|
||||||
|
, "--project-file=" <> cp
|
||||||
|
] ++ fmap T.unpack cabalArgs ++ [
|
||||||
|
"exe:haskell-language-server"
|
||||||
|
, "exe:haskell-language-server-wrapper"]
|
||||||
)
|
)
|
||||||
(Just workdir) "cabal" Nothing
|
(Just workdir) "cabal" Nothing
|
||||||
forM_ targets $ \target -> do
|
|
||||||
let cabal = "cabal"
|
|
||||||
args = ["list-bin", target]
|
|
||||||
CapturedProcess{..} <- lift $ executeOut cabal args (Just workdir)
|
|
||||||
case _exitCode of
|
|
||||||
ExitFailure i -> throwE (NonZeroExit i cabal args)
|
|
||||||
_ -> pure ()
|
|
||||||
let cbin = stripNewlineEnd . T.unpack . decUTF8Safe' $ _stdOut
|
|
||||||
copyFileE cbin (ghcInstallDir </> takeFileName cbin)
|
|
||||||
pure ghcInstallDir
|
pure ghcInstallDir
|
||||||
|
|
||||||
forM_ artifacts $ \artifact -> do
|
forM_ artifacts $ \artifact -> do
|
||||||
@@ -1102,7 +1108,7 @@ setGHC ver sghc = do
|
|||||||
pure $ Just (file <> "-" <> verS)
|
pure $ Just (file <> "-" <> verS)
|
||||||
|
|
||||||
-- create symlink
|
-- create symlink
|
||||||
forM mTargetFile $ \targetFile -> do
|
forM_ mTargetFile $ \targetFile -> do
|
||||||
let fullF = binDir </> targetFile <> exeExt
|
let fullF = binDir </> targetFile <> exeExt
|
||||||
fileWithExt = file <> exeExt
|
fileWithExt = file <> exeExt
|
||||||
destL <- lift $ ghcLinkDestination fileWithExt ver
|
destL <- lift $ ghcLinkDestination fileWithExt ver
|
||||||
@@ -1574,7 +1580,7 @@ listVersions lt' criteria = do
|
|||||||
|
|
||||||
currentGHCup :: Map.Map Version VersionInfo -> Maybe ListResult
|
currentGHCup :: Map.Map Version VersionInfo -> Maybe ListResult
|
||||||
currentGHCup av =
|
currentGHCup av =
|
||||||
let currentVer = fromJust $ pvpToVersion ghcUpVer
|
let currentVer = fromJust $ pvpToVersion ghcUpVer ""
|
||||||
listVer = Map.lookup currentVer av
|
listVer = Map.lookup currentVer av
|
||||||
latestVer = fst <$> headOf (getTagged Latest) av
|
latestVer = fst <$> headOf (getTagged Latest) av
|
||||||
recommendedVer = fst <$> headOf (getTagged Latest) av
|
recommendedVer = fst <$> headOf (getTagged Latest) av
|
||||||
@@ -2090,7 +2096,7 @@ compileGHC :: ( MonadMask m
|
|||||||
-> Either Version FilePath -- ^ version to bootstrap with
|
-> Either Version FilePath -- ^ version to bootstrap with
|
||||||
-> Maybe Int -- ^ jobs
|
-> Maybe Int -- ^ jobs
|
||||||
-> Maybe FilePath -- ^ build config
|
-> Maybe FilePath -- ^ build config
|
||||||
-> Maybe FilePath -- ^ patch directory
|
-> Maybe (Either FilePath [URI]) -- ^ patches
|
||||||
-> [Text] -- ^ additional args to ./configure
|
-> [Text] -- ^ additional args to ./configure
|
||||||
-> Maybe String -- ^ build flavour
|
-> Maybe String -- ^ build flavour
|
||||||
-> Bool
|
-> Bool
|
||||||
@@ -2119,7 +2125,7 @@ compileGHC :: ( MonadMask m
|
|||||||
]
|
]
|
||||||
m
|
m
|
||||||
GHCTargetVersion
|
GHCTargetVersion
|
||||||
compileGHC targetGhc ov bstrap jobs mbuildConfig patchdir aargs buildFlavour hadrian isolateDir
|
compileGHC targetGhc ov bstrap jobs mbuildConfig patches aargs buildFlavour hadrian isolateDir
|
||||||
= do
|
= do
|
||||||
PlatformRequest { .. } <- lift getPlatformReq
|
PlatformRequest { .. } <- lift getPlatformReq
|
||||||
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
GHCupInfo { _ghcupDownloads = dls } <- lift getGHCupInfo
|
||||||
@@ -2143,7 +2149,7 @@ compileGHC targetGhc ov bstrap jobs mbuildConfig patchdir aargs buildFlavour had
|
|||||||
workdir <- maybe (pure tmpUnpack)
|
workdir <- maybe (pure tmpUnpack)
|
||||||
(liftE . intoSubdir tmpUnpack)
|
(liftE . intoSubdir tmpUnpack)
|
||||||
(view dlSubdir dlInfo)
|
(view dlSubdir dlInfo)
|
||||||
forM_ patchdir (\dir -> liftE $ applyPatches dir workdir)
|
liftE $ applyAnyPatch patches workdir
|
||||||
|
|
||||||
pure (workdir, tmpUnpack, tver)
|
pure (workdir, tmpUnpack, tver)
|
||||||
|
|
||||||
@@ -2151,7 +2157,7 @@ compileGHC targetGhc ov bstrap jobs mbuildConfig patchdir aargs buildFlavour had
|
|||||||
Right GitBranch{..} -> do
|
Right GitBranch{..} -> do
|
||||||
tmpUnpack <- lift mkGhcupTmpDir
|
tmpUnpack <- lift mkGhcupTmpDir
|
||||||
let git args = execLogged "git" ("--no-pager":args) (Just tmpUnpack) "git" Nothing
|
let git args = execLogged "git" ("--no-pager":args) (Just tmpUnpack) "git" Nothing
|
||||||
tver <- reThrowAll @_ @'[PatchFailed, ProcessError, NotFoundInPATH] DownloadFailed $ do
|
tver <- reThrowAll @_ @'[PatchFailed, ProcessError, NotFoundInPATH, DigestError, DownloadFailed, GPGError] DownloadFailed $ do
|
||||||
let rep = fromMaybe "https://gitlab.haskell.org/ghc/ghc.git" repo
|
let rep = fromMaybe "https://gitlab.haskell.org/ghc/ghc.git" repo
|
||||||
lift $ logInfo $ "Fetching git repo " <> T.pack rep <> " at ref " <> T.pack ref <> " (this may take a while)"
|
lift $ logInfo $ "Fetching git repo " <> T.pack rep <> " at ref " <> T.pack ref <> " (this may take a while)"
|
||||||
lEM $ git [ "init" ]
|
lEM $ git [ "init" ]
|
||||||
@@ -2171,7 +2177,7 @@ compileGHC targetGhc ov bstrap jobs mbuildConfig patchdir aargs buildFlavour had
|
|||||||
|
|
||||||
lEM $ git [ "checkout", "FETCH_HEAD" ]
|
lEM $ git [ "checkout", "FETCH_HEAD" ]
|
||||||
lEM $ git [ "submodule", "update", "--init", "--depth", "1" ]
|
lEM $ git [ "submodule", "update", "--init", "--depth", "1" ]
|
||||||
forM_ patchdir (\dir -> liftE $ applyPatches dir tmpUnpack)
|
liftE $ applyAnyPatch patches tmpUnpack
|
||||||
lEM $ execWithGhcEnv "python3" ["./boot"] (Just tmpUnpack) "ghc-bootstrap"
|
lEM $ execWithGhcEnv "python3" ["./boot"] (Just tmpUnpack) "ghc-bootstrap"
|
||||||
lEM $ execWithGhcEnv "sh" ["./configure"] (Just tmpUnpack) "ghc-bootstrap"
|
lEM $ execWithGhcEnv "sh" ["./configure"] (Just tmpUnpack) "ghc-bootstrap"
|
||||||
CapturedProcess {..} <- lift $ makeOut
|
CapturedProcess {..} <- lift $ makeOut
|
||||||
@@ -2505,6 +2511,7 @@ compileGHC targetGhc ov bstrap jobs mbuildConfig patchdir aargs buildFlavour had
|
|||||||
execWithGhcEnv :: ( MonadReader env m
|
execWithGhcEnv :: ( MonadReader env m
|
||||||
, HasSettings env
|
, HasSettings env
|
||||||
, HasDirs env
|
, HasDirs env
|
||||||
|
, HasLog env
|
||||||
, MonadIO m
|
, MonadIO m
|
||||||
, MonadThrow m)
|
, MonadThrow m)
|
||||||
=> FilePath -- ^ thing to execute
|
=> FilePath -- ^ thing to execute
|
||||||
@@ -2576,7 +2583,7 @@ upgradeGHCup mtarget force' = do
|
|||||||
|
|
||||||
lift $ logInfo "Upgrading GHCup..."
|
lift $ logInfo "Upgrading GHCup..."
|
||||||
let latestVer = fromJust $ fst <$> getLatest dls GHCup
|
let latestVer = fromJust $ fst <$> getLatest dls GHCup
|
||||||
(Just ghcupPVPVer) <- pure $ pvpToVersion ghcUpVer
|
(Just ghcupPVPVer) <- pure $ pvpToVersion ghcUpVer ""
|
||||||
when (not force' && (latestVer <= ghcupPVPVer)) $ throwE NoUpdate
|
when (not force' && (latestVer <= ghcupPVPVer)) $ throwE NoUpdate
|
||||||
dli <- liftE $ getDownloadInfo GHCup latestVer
|
dli <- liftE $ getDownloadInfo GHCup latestVer
|
||||||
tmp <- lift withGHCupTmpDir
|
tmp <- lift withGHCupTmpDir
|
||||||
@@ -2845,3 +2852,25 @@ rmTmp = do
|
|||||||
let p = tmpdir </> f
|
let p = tmpdir </> f
|
||||||
logDebug $ "rm -rf " <> T.pack p
|
logDebug $ "rm -rf " <> T.pack p
|
||||||
rmPathForcibly p
|
rmPathForcibly p
|
||||||
|
|
||||||
|
|
||||||
|
applyAnyPatch :: ( MonadReader env m
|
||||||
|
, HasDirs env
|
||||||
|
, HasLog env
|
||||||
|
, HasSettings env
|
||||||
|
, MonadUnliftIO m
|
||||||
|
, MonadCatch m
|
||||||
|
, MonadResource m
|
||||||
|
, MonadThrow m
|
||||||
|
, MonadMask m
|
||||||
|
, MonadIO m)
|
||||||
|
=> Maybe (Either FilePath [URI])
|
||||||
|
-> FilePath
|
||||||
|
-> Excepts '[PatchFailed, DownloadFailed, DigestError, GPGError] m ()
|
||||||
|
applyAnyPatch Nothing _ = pure ()
|
||||||
|
applyAnyPatch (Just (Left pdir)) workdir = liftE $ applyPatches pdir workdir
|
||||||
|
applyAnyPatch (Just (Right uris)) workdir = do
|
||||||
|
tmpUnpack <- lift withGHCupTmpDir
|
||||||
|
forM_ uris $ \uri -> do
|
||||||
|
patch <- liftE $ download uri Nothing Nothing tmpUnpack Nothing False
|
||||||
|
liftE $ applyPatch patch workdir
|
||||||
|
|||||||
@@ -242,14 +242,18 @@ getBase uri = do
|
|||||||
e <- liftIO $ doesFileExist json_file
|
e <- liftIO $ doesFileExist json_file
|
||||||
currentTime <- liftIO getCurrentTime
|
currentTime <- liftIO getCurrentTime
|
||||||
Dirs { cacheDir } <- lift getDirs
|
Dirs { cacheDir } <- lift getDirs
|
||||||
|
Settings { metaCache } <- lift getSettings
|
||||||
|
|
||||||
-- for local files, let's short-circuit and ignore access time
|
-- for local files, let's short-circuit and ignore access time
|
||||||
if | scheme == "file" -> liftE $ download uri' Nothing Nothing cacheDir Nothing True
|
if | scheme == "file" -> liftE $ download uri' Nothing Nothing cacheDir Nothing True
|
||||||
| e -> do
|
| e -> do
|
||||||
accessTime <- liftIO $ getAccessTime json_file
|
accessTime <- fmap utcTimeToPOSIXSeconds $ liftIO $ getAccessTime json_file
|
||||||
|
let sinceLastAccess = utcTimeToPOSIXSeconds currentTime - accessTime
|
||||||
|
let cacheInterval = fromInteger metaCache
|
||||||
|
lift $ logDebug $ "last access was " <> T.pack (show sinceLastAccess) <> " ago, cache interval is " <> T.pack (show cacheInterval)
|
||||||
-- access time won't work on most linuxes, but we can try regardless
|
-- access time won't work on most linuxes, but we can try regardless
|
||||||
if | ((utcTimeToPOSIXSeconds currentTime - utcTimeToPOSIXSeconds accessTime) > 300) ->
|
if | metaCache <= 0 -> dlWithMod currentTime json_file
|
||||||
|
| (sinceLastAccess > cacheInterval) ->
|
||||||
-- no access in last 5 minutes, re-check upstream mod time
|
-- no access in last 5 minutes, re-check upstream mod time
|
||||||
dlWithMod currentTime json_file
|
dlWithMod currentTime json_file
|
||||||
| otherwise -> pure json_file
|
| otherwise -> pure json_file
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
{-# LANGUAGE CPP #-}
|
||||||
{-# LANGUAGE DataKinds #-}
|
{-# LANGUAGE DataKinds #-}
|
||||||
{-# LANGUAGE FlexibleContexts #-}
|
{-# LANGUAGE FlexibleContexts #-}
|
||||||
{-# LANGUAGE FlexibleInstances #-}
|
{-# LANGUAGE FlexibleInstances #-}
|
||||||
@@ -27,6 +28,9 @@ import GHCup.Utils.Logger
|
|||||||
import GHCup.Utils.Prelude
|
import GHCup.Utils.Prelude
|
||||||
import GHCup.Utils.String.QQ
|
import GHCup.Utils.String.QQ
|
||||||
|
|
||||||
|
#if !MIN_VERSION_base(4,13,0)
|
||||||
|
import Control.Monad.Fail ( MonadFail )
|
||||||
|
#endif
|
||||||
import Control.Applicative
|
import Control.Applicative
|
||||||
import Control.Exception.Safe
|
import Control.Exception.Safe
|
||||||
import Control.Monad
|
import Control.Monad
|
||||||
|
|||||||
@@ -294,6 +294,7 @@ instance NFData (URIRef Absolute) where
|
|||||||
|
|
||||||
data UserSettings = UserSettings
|
data UserSettings = UserSettings
|
||||||
{ uCache :: Maybe Bool
|
{ uCache :: Maybe Bool
|
||||||
|
, uMetaCache :: Maybe Integer
|
||||||
, uNoVerify :: Maybe Bool
|
, uNoVerify :: Maybe Bool
|
||||||
, uVerbose :: Maybe Bool
|
, uVerbose :: Maybe Bool
|
||||||
, uKeepDirs :: Maybe KeepDirs
|
, uKeepDirs :: Maybe KeepDirs
|
||||||
@@ -306,12 +307,13 @@ data UserSettings = UserSettings
|
|||||||
deriving (Show, GHC.Generic)
|
deriving (Show, GHC.Generic)
|
||||||
|
|
||||||
defaultUserSettings :: UserSettings
|
defaultUserSettings :: UserSettings
|
||||||
defaultUserSettings = UserSettings Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing
|
defaultUserSettings = UserSettings Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing Nothing
|
||||||
|
|
||||||
fromSettings :: Settings -> Maybe KeyBindings -> UserSettings
|
fromSettings :: Settings -> Maybe KeyBindings -> UserSettings
|
||||||
fromSettings Settings{..} Nothing =
|
fromSettings Settings{..} Nothing =
|
||||||
UserSettings {
|
UserSettings {
|
||||||
uCache = Just cache
|
uCache = Just cache
|
||||||
|
, uMetaCache = Just metaCache
|
||||||
, uNoVerify = Just noVerify
|
, uNoVerify = Just noVerify
|
||||||
, uVerbose = Just verbose
|
, uVerbose = Just verbose
|
||||||
, uKeepDirs = Just keepDirs
|
, uKeepDirs = Just keepDirs
|
||||||
@@ -335,6 +337,7 @@ fromSettings Settings{..} (Just KeyBindings{..}) =
|
|||||||
}
|
}
|
||||||
in UserSettings {
|
in UserSettings {
|
||||||
uCache = Just cache
|
uCache = Just cache
|
||||||
|
, uMetaCache = Just metaCache
|
||||||
, uNoVerify = Just noVerify
|
, uNoVerify = Just noVerify
|
||||||
, uVerbose = Just verbose
|
, uVerbose = Just verbose
|
||||||
, uKeepDirs = Just keepDirs
|
, uKeepDirs = Just keepDirs
|
||||||
@@ -410,6 +413,7 @@ instance NFData LeanAppState
|
|||||||
|
|
||||||
data Settings = Settings
|
data Settings = Settings
|
||||||
{ cache :: Bool
|
{ cache :: Bool
|
||||||
|
, metaCache :: Integer
|
||||||
, noVerify :: Bool
|
, noVerify :: Bool
|
||||||
, keepDirs :: KeepDirs
|
, keepDirs :: KeepDirs
|
||||||
, downloader :: Downloader
|
, downloader :: Downloader
|
||||||
@@ -421,6 +425,12 @@ data Settings = Settings
|
|||||||
}
|
}
|
||||||
deriving (Show, GHC.Generic)
|
deriving (Show, GHC.Generic)
|
||||||
|
|
||||||
|
defaultMetaCache :: Integer
|
||||||
|
defaultMetaCache = 300 -- 5 minutes
|
||||||
|
|
||||||
|
defaultSettings :: Settings
|
||||||
|
defaultSettings = Settings False defaultMetaCache False Never Curl False GHCupURL False GPGNone False
|
||||||
|
|
||||||
instance NFData Settings
|
instance NFData Settings
|
||||||
|
|
||||||
data Dirs = Dirs
|
data Dirs = Dirs
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ import Control.Monad.Reader
|
|||||||
import Control.Monad.Trans.Resource
|
import Control.Monad.Trans.Resource
|
||||||
hiding ( throwM )
|
hiding ( throwM )
|
||||||
import Control.Monad.IO.Unlift ( MonadUnliftIO( withRunInIO ) )
|
import Control.Monad.IO.Unlift ( MonadUnliftIO( withRunInIO ) )
|
||||||
|
import Data.Bifunctor ( first )
|
||||||
import Data.ByteString ( ByteString )
|
import Data.ByteString ( ByteString )
|
||||||
import Data.Either
|
import Data.Either
|
||||||
import Data.Foldable
|
import Data.Foldable
|
||||||
@@ -66,7 +67,7 @@ import Data.List
|
|||||||
import Data.List.NonEmpty ( NonEmpty( (:|) ))
|
import Data.List.NonEmpty ( NonEmpty( (:|) ))
|
||||||
import Data.Maybe
|
import Data.Maybe
|
||||||
import Data.Text ( Text )
|
import Data.Text ( Text )
|
||||||
import Data.Versions
|
import Data.Versions hiding ( patch )
|
||||||
import GHC.IO.Exception
|
import GHC.IO.Exception
|
||||||
import Haskus.Utils.Variant.Excepts
|
import Haskus.Utils.Variant.Excepts
|
||||||
import Optics
|
import Optics
|
||||||
@@ -110,8 +111,8 @@ import qualified Data.List.NonEmpty as NE
|
|||||||
-- >>> import Text.PrettyPrint.HughesPJClass ( prettyShow )
|
-- >>> import Text.PrettyPrint.HughesPJClass ( prettyShow )
|
||||||
-- >>> let lc = LoggerConfig { lcPrintDebug = False, consoleOutter = mempty, fileOutter = mempty, fancyColors = False }
|
-- >>> let lc = LoggerConfig { lcPrintDebug = False, consoleOutter = mempty, fileOutter = mempty, fancyColors = False }
|
||||||
-- >>> dirs' <- getAllDirs
|
-- >>> dirs' <- getAllDirs
|
||||||
-- >>> let installedVersions = [ ([pver|8.10.7|], Nothing), ([pver|8.10.4|], Nothing), ([pver|8.8.4|], Nothing), ([pver|8.8.3|], Nothing) ]
|
-- >>> let installedVersions = [ ([pver|8.10.7|], "-debug+lol", Nothing), ([pver|8.10.4|], "", Nothing), ([pver|8.8.4|], "", Nothing), ([pver|8.8.3|], "", Nothing) ]
|
||||||
-- >>> let settings = Settings True False Never Curl False GHCupURL True GPGNone False
|
-- >>> let settings = Settings True 0 False Never Curl False GHCupURL True GPGNone False
|
||||||
-- >>> let leanAppState = LeanAppState settings dirs' defaultKeyBindings lc
|
-- >>> let leanAppState = LeanAppState settings dirs' defaultKeyBindings lc
|
||||||
-- >>> cwd <- getCurrentDirectory
|
-- >>> cwd <- getCurrentDirectory
|
||||||
-- >>> (Right ref) <- pure $ parseURI strictURIParserOptions $ "file://" <> E.encodeUtf8 (T.pack cwd) <> "/data/metadata/" <> (urlBaseName . view pathL' $ ghcupURL)
|
-- >>> (Right ref) <- pure $ parseURI strictURIParserOptions $ "file://" <> E.encodeUtf8 (T.pack cwd) <> "/data/metadata/" <> (urlBaseName . view pathL' $ ghcupURL)
|
||||||
@@ -631,34 +632,34 @@ getGHCForPVP pvpIn mt = do
|
|||||||
ghcs <- rights <$> getInstalledGHCs
|
ghcs <- rights <$> getInstalledGHCs
|
||||||
-- we're permissive here... failed parse just means we have no match anyway
|
-- we're permissive here... failed parse just means we have no match anyway
|
||||||
let ghcs' = catMaybes $ flip fmap ghcs $ \GHCTargetVersion{..} -> do
|
let ghcs' = catMaybes $ flip fmap ghcs $ \GHCTargetVersion{..} -> do
|
||||||
pvp_ <- versionToPVP _tvVersion
|
(pvp_, rest) <- versionToPVP _tvVersion
|
||||||
pure (pvp_, _tvTarget)
|
pure (pvp_, rest, _tvTarget)
|
||||||
|
|
||||||
getGHCForPVP' pvpIn ghcs' mt
|
getGHCForPVP' pvpIn ghcs' mt
|
||||||
|
|
||||||
-- | Like 'getGHCForPVP', except with explicit input parameter.
|
-- | Like 'getGHCForPVP', except with explicit input parameter.
|
||||||
--
|
--
|
||||||
-- >>> fmap prettyShow $ getGHCForPVP' [pver|8|] installedVersions Nothing
|
-- >>> getGHCForPVP' [pver|8|] installedVersions Nothing
|
||||||
-- "Just 8.10.7"
|
-- Just (GHCTargetVersion {_tvTarget = Nothing, _tvVersion = Version {_vEpoch = Nothing, _vChunks = (Digits 8 :| []) :| [Digits 10 :| [],Digits 7 :| []], _vRel = [Str "debug" :| []], _vMeta = Just "lol"}})
|
||||||
-- >>> fmap prettyShow $ getGHCForPVP' [pver|8.8|] installedVersions Nothing
|
-- >>> fmap prettyShow $ getGHCForPVP' [pver|8.8|] installedVersions Nothing
|
||||||
-- "Just 8.8.4"
|
-- "Just 8.8.4"
|
||||||
-- >>> fmap prettyShow $ getGHCForPVP' [pver|8.10.4|] installedVersions Nothing
|
-- >>> fmap prettyShow $ getGHCForPVP' [pver|8.10.4|] installedVersions Nothing
|
||||||
-- "Just 8.10.4"
|
-- "Just 8.10.4"
|
||||||
getGHCForPVP' :: MonadThrow m
|
getGHCForPVP' :: MonadThrow m
|
||||||
=> PVP
|
=> PVP
|
||||||
-> [(PVP, Maybe Text)] -- ^ installed GHCs
|
-> [(PVP, Text, Maybe Text)] -- ^ installed GHCs
|
||||||
-> Maybe Text -- ^ the target triple
|
-> Maybe Text -- ^ the target triple
|
||||||
-> m (Maybe GHCTargetVersion)
|
-> m (Maybe GHCTargetVersion)
|
||||||
getGHCForPVP' pvpIn ghcs' mt = do
|
getGHCForPVP' pvpIn ghcs' mt = do
|
||||||
let mResult = lastMay
|
let mResult = lastMay
|
||||||
. sortBy (\(x, _) (y, _) -> compare x y)
|
. sortBy (\(x, _, _) (y, _, _) -> compare x y)
|
||||||
. filter
|
. filter
|
||||||
(\(pvp_, target) ->
|
(\(pvp_, _, target) ->
|
||||||
target == mt && matchPVPrefix pvp_ pvpIn
|
target == mt && matchPVPrefix pvp_ pvpIn
|
||||||
)
|
)
|
||||||
$ ghcs'
|
$ ghcs'
|
||||||
forM mResult $ \(pvp_, target) -> do
|
forM mResult $ \(pvp_, rest, target) -> do
|
||||||
ver' <- pvpToVersion pvp_
|
ver' <- pvpToVersion pvp_ rest
|
||||||
pure (GHCTargetVersion target ver')
|
pure (GHCTargetVersion target ver')
|
||||||
|
|
||||||
|
|
||||||
@@ -679,7 +680,7 @@ getLatestToolFor :: MonadThrow m
|
|||||||
getLatestToolFor tool pvpIn dls = do
|
getLatestToolFor tool pvpIn dls = do
|
||||||
let ls = fromMaybe [] $ preview (ix tool % to Map.toDescList) dls
|
let ls = fromMaybe [] $ preview (ix tool % to Map.toDescList) dls
|
||||||
let ps = catMaybes $ fmap (\(v, vi) -> (,vi) <$> versionToPVP v) ls
|
let ps = catMaybes $ fmap (\(v, vi) -> (,vi) <$> versionToPVP v) ls
|
||||||
pure . headMay . filter (\(v, _) -> matchPVPrefix pvpIn v) $ ps
|
pure . fmap (first fst) . headMay . filter (\((v, _), _) -> matchPVPrefix pvpIn v) $ ps
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -855,6 +856,7 @@ make :: ( MonadThrow m
|
|||||||
, MonadIO m
|
, MonadIO m
|
||||||
, MonadReader env m
|
, MonadReader env m
|
||||||
, HasDirs env
|
, HasDirs env
|
||||||
|
, HasLog env
|
||||||
, HasSettings env
|
, HasSettings env
|
||||||
)
|
)
|
||||||
=> [String]
|
=> [String]
|
||||||
@@ -890,15 +892,22 @@ applyPatches pdir ddir = do
|
|||||||
execBlank
|
execBlank
|
||||||
([s|.+\.(patch|diff)$|] :: ByteString)
|
([s|.+\.(patch|diff)$|] :: ByteString)
|
||||||
)
|
)
|
||||||
forM_ (sort patches) $ \patch' -> do
|
forM_ (sort patches) $ \patch' -> applyPatch patch' ddir
|
||||||
lift $ logInfo $ "Applying patch " <> T.pack patch'
|
|
||||||
fmap (either (const Nothing) Just)
|
|
||||||
(exec
|
applyPatch :: (MonadReader env m, HasDirs env, HasLog env, MonadIO m)
|
||||||
"patch"
|
=> FilePath -- ^ Patch
|
||||||
["-p1", "-i", patch']
|
-> FilePath -- ^ dir to apply patches in
|
||||||
(Just ddir)
|
-> Excepts '[PatchFailed] m ()
|
||||||
Nothing)
|
applyPatch patch ddir = do
|
||||||
!? PatchFailed
|
lift $ logInfo $ "Applying patch " <> T.pack patch
|
||||||
|
fmap (either (const Nothing) Just)
|
||||||
|
(exec
|
||||||
|
"patch"
|
||||||
|
["-p1", "-s", "-f", "-i", patch]
|
||||||
|
(Just ddir)
|
||||||
|
Nothing)
|
||||||
|
!? PatchFailed
|
||||||
|
|
||||||
|
|
||||||
-- | https://gitlab.haskell.org/ghc/ghc/-/issues/17353
|
-- | https://gitlab.haskell.org/ghc/ghc/-/issues/17353
|
||||||
|
|||||||
@@ -73,6 +73,7 @@ executeOut path args chdir = liftIO $ captureOutStreams $ do
|
|||||||
|
|
||||||
execLogged :: ( MonadReader env m
|
execLogged :: ( MonadReader env m
|
||||||
, HasSettings env
|
, HasSettings env
|
||||||
|
, HasLog env
|
||||||
, HasDirs env
|
, HasDirs env
|
||||||
, MonadIO m
|
, MonadIO m
|
||||||
, MonadThrow m)
|
, MonadThrow m)
|
||||||
@@ -85,6 +86,7 @@ execLogged :: ( MonadReader env m
|
|||||||
execLogged exe args chdir lfile env = do
|
execLogged exe args chdir lfile env = do
|
||||||
Settings {..} <- getSettings
|
Settings {..} <- getSettings
|
||||||
Dirs {..} <- getDirs
|
Dirs {..} <- getDirs
|
||||||
|
logDebug $ T.pack $ "Running " <> exe <> " with arguments " <> show args
|
||||||
let logfile = logsDir </> lfile <> ".log"
|
let logfile = logsDir </> lfile <> ".log"
|
||||||
liftIO $ bracket (openFd logfile WriteOnly (Just newFilePerms) defaultFileFlags{ append = True })
|
liftIO $ bracket (openFd logfile WriteOnly (Just newFilePerms) defaultFileFlags{ append = True })
|
||||||
closeFd
|
closeFd
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ module GHCup.Utils.File.Windows where
|
|||||||
import {-# SOURCE #-} GHCup.Utils ( getLinkTarget, pathIsLink )
|
import {-# SOURCE #-} GHCup.Utils ( getLinkTarget, pathIsLink )
|
||||||
import GHCup.Utils.Dirs
|
import GHCup.Utils.Dirs
|
||||||
import GHCup.Utils.File.Common
|
import GHCup.Utils.File.Common
|
||||||
|
import GHCup.Utils.Logger
|
||||||
import GHCup.Types
|
import GHCup.Types
|
||||||
import GHCup.Types.Optics
|
import GHCup.Types.Optics
|
||||||
|
|
||||||
@@ -40,6 +41,7 @@ import qualified Control.Exception as EX
|
|||||||
import qualified Data.ByteString as BS
|
import qualified Data.ByteString as BS
|
||||||
import qualified Data.ByteString.Lazy as BL
|
import qualified Data.ByteString.Lazy as BL
|
||||||
import qualified Data.Map.Strict as Map
|
import qualified Data.Map.Strict as Map
|
||||||
|
import qualified Data.Text as T
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -149,6 +151,7 @@ executeOut path args chdir = do
|
|||||||
|
|
||||||
execLogged :: ( MonadReader env m
|
execLogged :: ( MonadReader env m
|
||||||
, HasDirs env
|
, HasDirs env
|
||||||
|
, HasLog env
|
||||||
, HasSettings env
|
, HasSettings env
|
||||||
, MonadIO m
|
, MonadIO m
|
||||||
, MonadThrow m)
|
, MonadThrow m)
|
||||||
@@ -160,6 +163,7 @@ execLogged :: ( MonadReader env m
|
|||||||
-> m (Either ProcessError ())
|
-> m (Either ProcessError ())
|
||||||
execLogged exe args chdir lfile env = do
|
execLogged exe args chdir lfile env = do
|
||||||
Dirs {..} <- getDirs
|
Dirs {..} <- getDirs
|
||||||
|
logDebug $ T.pack $ "Running " <> exe <> " with arguments " <> show args
|
||||||
let stdoutLogfile = logsDir </> lfile <> ".stdout.log"
|
let stdoutLogfile = logsDir </> lfile <> ".stdout.log"
|
||||||
stderrLogfile = logsDir </> lfile <> ".stderr.log"
|
stderrLogfile = logsDir </> lfile <> ".stderr.log"
|
||||||
cp <- createProcessWithMingwPath ((proc exe args)
|
cp <- createProcessWithMingwPath ((proc exe args)
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ import Control.Monad.IO.Class
|
|||||||
import Control.Monad.Reader
|
import Control.Monad.Reader
|
||||||
import Data.Bifunctor
|
import Data.Bifunctor
|
||||||
import Data.ByteString ( ByteString )
|
import Data.ByteString ( ByteString )
|
||||||
import Data.List ( nub, intercalate, stripPrefix, isPrefixOf, dropWhileEnd )
|
import Data.List ( nub, intercalate, stripPrefix, isPrefixOf, dropWhileEnd, intersperse )
|
||||||
import Data.Maybe
|
import Data.Maybe
|
||||||
import Data.Foldable
|
import Data.Foldable
|
||||||
import Data.List.NonEmpty ( NonEmpty( (:|) ))
|
import Data.List.NonEmpty ( NonEmpty( (:|) ))
|
||||||
@@ -313,18 +313,46 @@ removeLensFieldLabel str' =
|
|||||||
maybe str' T.unpack . T.stripPrefix (T.pack "_") . T.pack $ str'
|
maybe str' T.unpack . T.stripPrefix (T.pack "_") . T.pack $ str'
|
||||||
|
|
||||||
|
|
||||||
pvpToVersion :: MonadThrow m => PVP -> m Version
|
pvpToVersion :: MonadThrow m => PVP -> Text -> m Version
|
||||||
pvpToVersion =
|
pvpToVersion pvp_ rest =
|
||||||
either (\_ -> throwM $ ParseError "Couldn't convert PVP to Version") pure . version . prettyPVP
|
either (\_ -> throwM $ ParseError "Couldn't convert PVP to Version") pure . version . (<> rest) . prettyPVP $ pvp_
|
||||||
|
|
||||||
versionToPVP :: MonadThrow m => Version -> m PVP
|
-- | Convert a version to a PVP and unparsable rest.
|
||||||
versionToPVP v = either (\_ -> alternative v) pure . pvp . prettyVer $ v
|
--
|
||||||
|
-- -- prop> \v -> let (Just (pvp', r)) = versionToPVP v in pvpToVersion pvp' r === Just v
|
||||||
|
versionToPVP :: MonadThrow m => Version -> m (PVP, Text)
|
||||||
|
versionToPVP (Version (Just _) _ _ _) = throwM $ ParseError "Unexpected epoch"
|
||||||
|
versionToPVP v = either (\_ -> (, rest v) <$> alternative v) (pure . (, mempty)) . pvp . prettyVer $ v
|
||||||
where
|
where
|
||||||
alternative :: MonadThrow m => Version -> m PVP
|
alternative :: MonadThrow m => Version -> m PVP
|
||||||
alternative v' = case NE.takeWhile isDigit (_vChunks v') of
|
alternative v' = case NE.takeWhile isDigit (_vChunks v') of
|
||||||
[] -> throwM $ ParseError "Couldn't convert Version to PVP"
|
[] -> throwM $ ParseError "Couldn't convert Version to PVP"
|
||||||
xs -> pure $ pvpFromList (unsafeDigit <$> xs)
|
xs -> pure $ pvpFromList (unsafeDigit <$> xs)
|
||||||
|
|
||||||
|
rest :: Version -> Text
|
||||||
|
rest (Version _ cs pr me) =
|
||||||
|
let chunks = NE.dropWhile isDigit cs
|
||||||
|
ver = intersperse (T.pack ".") . chunksAsT $ chunks
|
||||||
|
me' = maybe [] (\m -> [T.pack "+",m]) me
|
||||||
|
pr' = foldable [] (T.pack "-" :) $ intersperse (T.pack ".") (chunksAsT pr)
|
||||||
|
prefix = case (ver, pr', me') of
|
||||||
|
(_:_, _, _) -> T.pack "."
|
||||||
|
_ -> T.pack ""
|
||||||
|
in prefix <> mconcat (ver <> pr' <> me')
|
||||||
|
where
|
||||||
|
chunksAsT :: Functor t => t VChunk -> t Text
|
||||||
|
chunksAsT = fmap (foldMap f)
|
||||||
|
where
|
||||||
|
f :: VUnit -> Text
|
||||||
|
f (Digits i) = T.pack $ show i
|
||||||
|
f (Str s) = s
|
||||||
|
|
||||||
|
foldable :: Foldable f => f b -> (f a -> f b) -> f a -> f b
|
||||||
|
foldable d g f | null f = d
|
||||||
|
| otherwise = g f
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
isDigit :: VChunk -> Bool
|
isDigit :: VChunk -> Bool
|
||||||
isDigit (Digits _ :| []) = True
|
isDigit (Digits _ :| []) = True
|
||||||
isDigit _ = False
|
isDigit _ = False
|
||||||
|
|||||||
@@ -53,6 +53,9 @@ deriving instance Data VUnit
|
|||||||
|
|
||||||
#if !MIN_VERSION_base(4,13,0)
|
#if !MIN_VERSION_base(4,13,0)
|
||||||
deriving instance Lift (NonEmpty Word)
|
deriving instance Lift (NonEmpty Word)
|
||||||
|
deriving instance Lift (NonEmpty VChunk)
|
||||||
|
deriving instance Lift (NonEmpty MChunk)
|
||||||
|
deriving instance Lift (NonEmpty VUnit)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
qq :: (Text -> Q Exp) -> QuasiQuoter
|
qq :: (Text -> Q Exp) -> QuasiQuoter
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
plat="$(uname -s)"
|
plat="$(uname -s)"
|
||||||
arch=$(uname -m)
|
arch=$(uname -m)
|
||||||
ghver="0.1.17.2"
|
ghver="0.1.17.3"
|
||||||
base_url="https://downloads.haskell.org/~ghcup"
|
base_url="https://downloads.haskell.org/~ghcup"
|
||||||
|
|
||||||
export GHCUP_SKIP_UPDATE_CHECK=yes
|
export GHCUP_SKIP_UPDATE_CHECK=yes
|
||||||
|
|||||||
@@ -246,6 +246,7 @@ if ($Silent -and !($InstallDir)) {
|
|||||||
$GhcupBasePrefix = ('{0}\' -f $GhcupBasePrefix)
|
$GhcupBasePrefix = ('{0}\' -f $GhcupBasePrefix)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$GhcupBasePrefix = $GhcupBasePrefix.TrimEnd().TrimStart()
|
||||||
if (!($GhcupBasePrefix)) {
|
if (!($GhcupBasePrefix)) {
|
||||||
Print-Msg -color Red -msg "No directory specified!"
|
Print-Msg -color Red -msg "No directory specified!"
|
||||||
} elseif (!(Test-Path -LiteralPath ('{0}' -f $GhcupBasePrefix))) {
|
} elseif (!(Test-Path -LiteralPath ('{0}' -f $GhcupBasePrefix))) {
|
||||||
@@ -333,6 +334,7 @@ if ($CabalDir) {
|
|||||||
$CabalDirPrompt = Read-Host
|
$CabalDirPrompt = Read-Host
|
||||||
$CabDirEnv = ($defaultCabalDir,$CabalDirPrompt)[[bool]$CabalDirPrompt]
|
$CabDirEnv = ($defaultCabalDir,$CabalDirPrompt)[[bool]$CabalDirPrompt]
|
||||||
|
|
||||||
|
$CabDirEnv = $CabDirEnv.TrimEnd().TrimStart()
|
||||||
if (!($CabDirEnv)) {
|
if (!($CabDirEnv)) {
|
||||||
Print-Msg -color Red -msg "No directory specified!"
|
Print-Msg -color Red -msg "No directory specified!"
|
||||||
} elseif (!(Split-Path -IsAbsolute -Path "$CabDirEnv")) {
|
} elseif (!(Split-Path -IsAbsolute -Path "$CabDirEnv")) {
|
||||||
@@ -444,6 +446,7 @@ if (!(Test-Path -Path ('{0}' -f $MsysDir))) {
|
|||||||
Print-Msg -color Magenta -msg 'Input existing MSys2 toolchain directory:'
|
Print-Msg -color Magenta -msg 'Input existing MSys2 toolchain directory:'
|
||||||
$MsysDir = Read-Host
|
$MsysDir = Read-Host
|
||||||
}
|
}
|
||||||
|
$MsysDir = $MsysDir.TrimEnd().TrimStart()
|
||||||
if (!($MsysDir)) {
|
if (!($MsysDir)) {
|
||||||
Print-Msg -color Red -msg "No directory specified!"
|
Print-Msg -color Red -msg "No directory specified!"
|
||||||
} elseif (!(Test-Path -LiteralPath ('{0}' -f $MsysDir))) {
|
} elseif (!(Test-Path -LiteralPath ('{0}' -f $MsysDir))) {
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ extra-deps:
|
|||||||
- composition-prelude-3.0.0.2@sha256:1ffed216bd28d810fce0b5be83a661e2a892696d73b3f8de5c0f5edb9b5f0090,1216
|
- composition-prelude-3.0.0.2@sha256:1ffed216bd28d810fce0b5be83a661e2a892696d73b3f8de5c0f5edb9b5f0090,1216
|
||||||
- haskus-utils-data-1.4@sha256:bfa94363b94b14779edd6834fbd59dbb847c3d7b8f48e3844f456ffdc077da4a,1466
|
- haskus-utils-data-1.4@sha256:bfa94363b94b14779edd6834fbd59dbb847c3d7b8f48e3844f456ffdc077da4a,1466
|
||||||
- haskus-utils-types-1.5.1@sha256:991c472f4e751e2f0d7aab6ad4220ef151d6160876dcf0511bbf876bbd432020,1298
|
- haskus-utils-types-1.5.1@sha256:991c472f4e751e2f0d7aab6ad4220ef151d6160876dcf0511bbf876bbd432020,1298
|
||||||
- haskus-utils-variant-3.1@sha256:e602dd23e068c98d03c1027af20503addef8df6368577622453f44ccabea2a5b,2159
|
|
||||||
- heaps-0.3.6.1@sha256:7928b759ca5180d35722c45948c0bde264229f3c99c1888188a3d9285f13d3d2,1340
|
- heaps-0.3.6.1@sha256:7928b759ca5180d35722c45948c0bde264229f3c99c1888188a3d9285f13d3d2,1340
|
||||||
- hpath-filepath-0.10.4@sha256:e9e44fb5fdbade7f30b5b5451257dbee15b6ef1aae4060034d73008bb3b5d878,1269
|
- hpath-filepath-0.10.4@sha256:e9e44fb5fdbade7f30b5b5451257dbee15b6ef1aae4060034d73008bb3b5d878,1269
|
||||||
- hpath-posix-0.13.3@sha256:abe472cf16bccd3a8b8814865ed3551a728fde0f3a2baea2acc03023bec6c565,1615
|
- hpath-posix-0.13.3@sha256:abe472cf16bccd3a8b8814865ed3551a728fde0f3a2baea2acc03023bec6c565,1615
|
||||||
@@ -40,6 +39,11 @@ extra-deps:
|
|||||||
- xor-0.0.1.0@sha256:f8362b4a68562b9afbcd727ff64c1a303970df3a032e0033d2f4c094c3501df3,2243
|
- xor-0.0.1.0@sha256:f8362b4a68562b9afbcd727ff64c1a303970df3a032e0033d2f4c094c3501df3,2243
|
||||||
- yaml-streamly-0.12.0
|
- yaml-streamly-0.12.0
|
||||||
|
|
||||||
|
- git: https://github.com/hasufell/packages.git
|
||||||
|
commit: cc0b4688f8bb374fa92f17c856949de795b56291
|
||||||
|
subdirs:
|
||||||
|
- haskus-utils-variant
|
||||||
|
|
||||||
flags:
|
flags:
|
||||||
http-io-streams:
|
http-io-streams:
|
||||||
brotli: false
|
brotli: false
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
module GHCup.Types.JSONSpec where
|
module GHCup.Types.JSONSpec where
|
||||||
|
|
||||||
import GHCup.ArbitraryTypes ()
|
import GHCup.ArbitraryTypes ()
|
||||||
import GHCup.Types
|
import GHCup.Types hiding ( defaultSettings )
|
||||||
import GHCup.Types.JSON ()
|
import GHCup.Types.JSON ()
|
||||||
|
|
||||||
import Test.Aeson.GenericSpecs
|
import Test.Aeson.GenericSpecs
|
||||||
|
|||||||
Reference in New Issue
Block a user