Compare commits
16 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
92bd333552
|
|||
|
70a451b63e
|
|||
|
cfe6c47cd7
|
|||
|
8eeb32c495
|
|||
|
fdcd6822c4
|
|||
|
71390c84da
|
|||
|
84d01b1091
|
|||
|
8f9faaa39e
|
|||
|
0898244b2a
|
|||
|
0c70feb09c
|
|||
|
f9a38e616d
|
|||
|
e511fc3c0a
|
|||
|
3ff670134c
|
|||
|
4c0160bb28
|
|||
|
c1e0baedd3
|
|||
|
8f7d937e26
|
@@ -5,6 +5,11 @@
|
|||||||
* Vastly improve shell completions wrt [#242](https://gitlab.haskell.org/haskell/ghcup-hs/-/merge_requests/242)
|
* Vastly improve shell completions wrt [#242](https://gitlab.haskell.org/haskell/ghcup-hs/-/merge_requests/242)
|
||||||
* Fix 'ghcup install cabal/hls/stack --set' wrt [#324](https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/324)
|
* Fix 'ghcup install cabal/hls/stack --set' wrt [#324](https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/324)
|
||||||
* Fix bad error message wrt [#323](https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/323)
|
* Fix bad error message wrt [#323](https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/323)
|
||||||
|
* Use predictable /tmp names for `ghcup run`, fixes [#329](https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/329)
|
||||||
|
* Fix bug with isolated installation of not previously installed versions
|
||||||
|
* Add `--no-set` to install commands, fixes [#330](https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/330)
|
||||||
|
* Fix serious bug in `ghcup list --raw-format -t <tool> -c installed`
|
||||||
|
* Overhaul metadata merging and add `ghcup config add-release-channel URI` wrt [#328](https://gitlab.haskell.org/haskell/ghcup-hs/-/issues/328)
|
||||||
|
|
||||||
## 0.1.17.5 -- 2022-02-26
|
## 0.1.17.5 -- 2022-02-26
|
||||||
|
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ data Command
|
|||||||
#ifndef DISABLE_UPGRADE
|
#ifndef DISABLE_UPGRADE
|
||||||
| Upgrade UpgradeOpts Bool
|
| Upgrade UpgradeOpts Bool
|
||||||
#endif
|
#endif
|
||||||
| ToolRequirements
|
| ToolRequirements ToolReqOpts
|
||||||
| ChangeLog ChangeLogOptions
|
| ChangeLog ChangeLogOptions
|
||||||
| Nuke
|
| Nuke
|
||||||
#if defined(BRICK)
|
#if defined(BRICK)
|
||||||
@@ -289,8 +289,8 @@ com =
|
|||||||
((\_ -> DInfo) <$> info helper (progDesc "Show debug info"))
|
((\_ -> DInfo) <$> info helper (progDesc "Show debug info"))
|
||||||
<> command
|
<> command
|
||||||
"tool-requirements"
|
"tool-requirements"
|
||||||
( (\_ -> ToolRequirements)
|
( ToolRequirements
|
||||||
<$> info helper
|
<$> info (toolReqP <**> helper)
|
||||||
(progDesc "Show the requirements for ghc/cabal")
|
(progDesc "Show the requirements for ghc/cabal")
|
||||||
)
|
)
|
||||||
<> command
|
<> command
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
{-# LANGUAGE OverloadedStrings #-}
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
{-# LANGUAGE DuplicateRecordFields #-}
|
{-# LANGUAGE DuplicateRecordFields #-}
|
||||||
{-# LANGUAGE RankNTypes #-}
|
{-# LANGUAGE RankNTypes #-}
|
||||||
|
{-# LANGUAGE ExplicitForAll #-}
|
||||||
|
|
||||||
module GHCup.OptParse.Config where
|
module GHCup.OptParse.Config where
|
||||||
|
|
||||||
@@ -17,6 +18,7 @@ import GHCup.Utils
|
|||||||
import GHCup.Utils.Prelude
|
import GHCup.Utils.Prelude
|
||||||
import GHCup.Utils.Logger
|
import GHCup.Utils.Logger
|
||||||
import GHCup.Utils.String.QQ
|
import GHCup.Utils.String.QQ
|
||||||
|
import GHCup.OptParse.Common
|
||||||
|
|
||||||
#if !MIN_VERSION_base(4,13,0)
|
#if !MIN_VERSION_base(4,13,0)
|
||||||
import Control.Monad.Fail ( MonadFail )
|
import Control.Monad.Fail ( MonadFail )
|
||||||
@@ -27,10 +29,11 @@ import Control.Monad.Trans.Resource
|
|||||||
import Data.Functor
|
import Data.Functor
|
||||||
import Data.Maybe
|
import Data.Maybe
|
||||||
import Haskus.Utils.Variant.Excepts
|
import Haskus.Utils.Variant.Excepts
|
||||||
import Options.Applicative hiding ( style )
|
import Options.Applicative hiding ( style, ParseError )
|
||||||
import Options.Applicative.Help.Pretty ( text )
|
import Options.Applicative.Help.Pretty ( text )
|
||||||
import Prelude hiding ( appendFile )
|
import Prelude hiding ( appendFile )
|
||||||
import System.Exit
|
import System.Exit
|
||||||
|
import URI.ByteString hiding ( uriParser )
|
||||||
|
|
||||||
import qualified Data.Text as T
|
import qualified Data.Text as T
|
||||||
import qualified Data.ByteString.UTF8 as UTF8
|
import qualified Data.ByteString.UTF8 as UTF8
|
||||||
@@ -49,6 +52,7 @@ data ConfigCommand
|
|||||||
= ShowConfig
|
= ShowConfig
|
||||||
| SetConfig String (Maybe String)
|
| SetConfig String (Maybe String)
|
||||||
| InitConfig
|
| InitConfig
|
||||||
|
| AddReleaseChannel URI
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -62,6 +66,7 @@ configP = subparser
|
|||||||
( command "init" initP
|
( command "init" initP
|
||||||
<> command "set" setP -- [set] KEY VALUE at help lhs
|
<> command "set" setP -- [set] KEY VALUE at help lhs
|
||||||
<> command "show" showP
|
<> command "show" showP
|
||||||
|
<> command "add-release-channel" addP
|
||||||
)
|
)
|
||||||
<|> argsP -- add show for a single option
|
<|> argsP -- add show for a single option
|
||||||
<|> pure ShowConfig
|
<|> pure ShowConfig
|
||||||
@@ -70,6 +75,8 @@ configP = subparser
|
|||||||
showP = info (pure ShowConfig) (progDesc "Show current config (default)")
|
showP = info (pure ShowConfig) (progDesc "Show current config (default)")
|
||||||
setP = info argsP (progDesc "Set config KEY to VALUE (or specify as single json value)" <> footerDoc (Just $ text configSetFooter))
|
setP = info argsP (progDesc "Set config KEY to VALUE (or specify as single json value)" <> footerDoc (Just $ text configSetFooter))
|
||||||
argsP = SetConfig <$> argument str (metavar "<JSON_VALUE | YAML_KEY>") <*> optional (argument str (metavar "YAML_VALUE"))
|
argsP = SetConfig <$> argument str (metavar "<JSON_VALUE | YAML_KEY>") <*> optional (argument str (metavar "YAML_VALUE"))
|
||||||
|
addP = info (AddReleaseChannel <$> argument (eitherReader uriParser) (metavar "URI" <> completer fileUri))
|
||||||
|
(progDesc "Add a release channel from a URI")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -114,23 +121,18 @@ formatConfig :: UserSettings -> String
|
|||||||
formatConfig = UTF8.toString . Y.encode
|
formatConfig = UTF8.toString . Y.encode
|
||||||
|
|
||||||
|
|
||||||
updateSettings :: Monad m => UTF8.ByteString -> Settings -> Excepts '[JSONError] m Settings
|
updateSettings :: UserSettings -> Settings -> Settings
|
||||||
updateSettings config' settings = do
|
updateSettings UserSettings{..} Settings{..} =
|
||||||
settings' <- lE' (JSONDecodeError . displayException) . Y.decodeEither' $ config'
|
let cache' = fromMaybe cache uCache
|
||||||
pure $ mergeConf settings' settings
|
metaCache' = fromMaybe metaCache uMetaCache
|
||||||
where
|
noVerify' = fromMaybe noVerify uNoVerify
|
||||||
mergeConf :: UserSettings -> Settings -> Settings
|
keepDirs' = fromMaybe keepDirs uKeepDirs
|
||||||
mergeConf UserSettings{..} Settings{..} =
|
downloader' = fromMaybe downloader uDownloader
|
||||||
let cache' = fromMaybe cache uCache
|
verbose' = fromMaybe verbose uVerbose
|
||||||
metaCache' = fromMaybe metaCache uMetaCache
|
urlSource' = fromMaybe urlSource uUrlSource
|
||||||
noVerify' = fromMaybe noVerify uNoVerify
|
noNetwork' = fromMaybe noNetwork uNoNetwork
|
||||||
keepDirs' = fromMaybe keepDirs uKeepDirs
|
gpgSetting' = fromMaybe gpgSetting uGPGSetting
|
||||||
downloader' = fromMaybe downloader uDownloader
|
in Settings cache' metaCache' noVerify' keepDirs' downloader' verbose' urlSource' noNetwork' gpgSetting' noColor
|
||||||
verbose' = fromMaybe verbose uVerbose
|
|
||||||
urlSource' = fromMaybe urlSource uUrlSource
|
|
||||||
noNetwork' = fromMaybe noNetwork uNoNetwork
|
|
||||||
gpgSetting' = fromMaybe gpgSetting uGPGSetting
|
|
||||||
in Settings cache' metaCache' noVerify' keepDirs' downloader' verbose' urlSource' noNetwork' gpgSetting' noColor
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -140,7 +142,7 @@ updateSettings config' settings = do
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
config :: ( Monad m
|
config :: forall m. ( Monad m
|
||||||
, MonadMask m
|
, MonadMask m
|
||||||
, MonadUnliftIO m
|
, MonadUnliftIO m
|
||||||
, MonadFail m
|
, MonadFail m
|
||||||
@@ -161,27 +163,42 @@ config configCommand settings keybindings runLogger = case configCommand of
|
|||||||
liftIO $ putStrLn $ formatConfig $ fromSettings settings (Just keybindings)
|
liftIO $ putStrLn $ formatConfig $ fromSettings settings (Just keybindings)
|
||||||
pure ExitSuccess
|
pure ExitSuccess
|
||||||
|
|
||||||
(SetConfig k (Just v)) ->
|
(SetConfig k mv) -> do
|
||||||
case v of
|
r <- runE @'[JSONError, ParseError] $ do
|
||||||
"" -> do
|
case mv of
|
||||||
runLogger $ logError "Empty values are not allowed"
|
Just "" ->
|
||||||
pure $ ExitFailure 55
|
throwE $ ParseError "Empty values are not allowed"
|
||||||
_ -> doConfig (k <> ": " <> v <> "\n")
|
Nothing -> do
|
||||||
|
usersettings <- decodeSettings k
|
||||||
|
lift $ doConfig usersettings
|
||||||
|
pure ()
|
||||||
|
Just v -> do
|
||||||
|
usersettings <- decodeSettings (k <> ": " <> v <> "\n")
|
||||||
|
lift $ doConfig usersettings
|
||||||
|
pure ()
|
||||||
|
case r of
|
||||||
|
VRight _ -> pure ExitSuccess
|
||||||
|
VLeft (V (JSONDecodeError e)) -> do
|
||||||
|
runLogger $ logError $ "Error decoding config: " <> T.pack e
|
||||||
|
pure $ ExitFailure 65
|
||||||
|
VLeft _ -> pure $ ExitFailure 65
|
||||||
|
|
||||||
(SetConfig json Nothing) -> doConfig json
|
AddReleaseChannel uri -> do
|
||||||
|
case urlSource settings of
|
||||||
|
AddSource xs -> do
|
||||||
|
doConfig (defaultUserSettings { uUrlSource = Just $ AddSource (xs <> [Right uri]) })
|
||||||
|
pure ExitSuccess
|
||||||
|
_ -> do
|
||||||
|
doConfig (defaultUserSettings { uUrlSource = Just $ AddSource [Right uri] })
|
||||||
|
pure ExitSuccess
|
||||||
|
|
||||||
where
|
where
|
||||||
doConfig val = do
|
doConfig :: MonadIO m => UserSettings -> m ()
|
||||||
r <- runE @'[JSONError] $ do
|
doConfig usersettings = do
|
||||||
settings' <- updateSettings (UTF8.fromString val) settings
|
let settings' = updateSettings usersettings settings
|
||||||
path <- liftIO getConfigFilePath
|
path <- liftIO getConfigFilePath
|
||||||
liftIO $ writeFile path $ formatConfig $ fromSettings settings' (Just keybindings)
|
liftIO $ writeFile path $ formatConfig $ fromSettings settings' (Just keybindings)
|
||||||
lift $ runLogger $ logDebug $ T.pack $ show settings'
|
runLogger $ logDebug $ T.pack $ show settings'
|
||||||
pure ()
|
pure ()
|
||||||
|
|
||||||
case r of
|
decodeSettings = lE' (JSONDecodeError . displayException) . Y.decodeEither' . UTF8.fromString
|
||||||
VRight _ -> pure ExitSuccess
|
|
||||||
VLeft (V (JSONDecodeError e)) -> do
|
|
||||||
runLogger $ logError $ "Error decoding config: " <> T.pack e
|
|
||||||
pure $ ExitFailure 65
|
|
||||||
VLeft _ -> pure $ ExitFailure 65
|
|
||||||
|
|||||||
@@ -143,11 +143,11 @@ printListResult no_color raw lr = do
|
|||||||
)
|
)
|
||||||
$ lr
|
$ lr
|
||||||
let cols =
|
let cols =
|
||||||
foldr (\xs ys -> zipWith (:) xs ys) (replicate (length rows) []) rows
|
foldr (\xs ys -> zipWith (:) xs ys) (repeat []) rows
|
||||||
lengths = fmap (maximum . fmap strWidth) cols
|
lengths = fmap (maximum . fmap strWidth) cols
|
||||||
padded = fmap (\xs -> zipWith padTo xs lengths) rows
|
padded = fmap (\xs -> zipWith padTo xs lengths) rows
|
||||||
|
|
||||||
forM_ padded $ \row -> putStrLn $ unwords row
|
forM_ (if raw then rows else padded) $ \row -> putStrLn $ unwords row
|
||||||
where
|
where
|
||||||
|
|
||||||
padTo str' x =
|
padTo str' x =
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import GHCup.Utils.File
|
|||||||
import GHCup.OptParse.Common
|
import GHCup.OptParse.Common
|
||||||
import GHCup.Errors
|
import GHCup.Errors
|
||||||
import GHCup.Types
|
import GHCup.Types
|
||||||
import GHCup.Types.Optics ( getDirs )
|
import GHCup.Types.Optics
|
||||||
import GHCup.Utils.Logger
|
import GHCup.Utils.Logger
|
||||||
import GHCup.Utils.String.QQ
|
import GHCup.Utils.String.QQ
|
||||||
|
|
||||||
@@ -35,7 +35,6 @@ import Prelude hiding ( appendFile )
|
|||||||
import System.Directory
|
import System.Directory
|
||||||
import System.FilePath
|
import System.FilePath
|
||||||
import System.Environment
|
import System.Environment
|
||||||
import System.IO.Temp
|
|
||||||
import System.Exit
|
import System.Exit
|
||||||
import Text.PrettyPrint.HughesPJClass ( prettyShow )
|
import Text.PrettyPrint.HughesPJClass ( prettyShow )
|
||||||
|
|
||||||
@@ -188,14 +187,16 @@ runLeanRUN leanAppstate =
|
|||||||
@RunEffects
|
@RunEffects
|
||||||
|
|
||||||
runRUN :: MonadUnliftIO m
|
runRUN :: MonadUnliftIO m
|
||||||
=> (ReaderT AppState m (VEither RunEffects a) -> m (VEither RunEffects a))
|
=> IO AppState
|
||||||
-> Excepts RunEffects (ResourceT (ReaderT AppState m)) a
|
-> Excepts RunEffects (ResourceT (ReaderT AppState m)) a
|
||||||
-> m (VEither RunEffects a)
|
-> m (VEither RunEffects a)
|
||||||
runRUN runAppState =
|
runRUN appState action' = do
|
||||||
runAppState
|
s' <- liftIO appState
|
||||||
|
flip runReaderT s'
|
||||||
. runResourceT
|
. runResourceT
|
||||||
. runE
|
. runE
|
||||||
@RunEffects
|
@RunEffects
|
||||||
|
$ action'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -213,110 +214,182 @@ run :: forall m.
|
|||||||
, MonadUnliftIO m
|
, MonadUnliftIO m
|
||||||
)
|
)
|
||||||
=> RunOptions
|
=> RunOptions
|
||||||
-> (forall a. ReaderT AppState m (VEither RunEffects a) -> m (VEither RunEffects a))
|
-> IO AppState
|
||||||
-> LeanAppState
|
-> LeanAppState
|
||||||
-> (ReaderT LeanAppState m () -> m ())
|
-> (ReaderT LeanAppState m () -> m ())
|
||||||
-> m ExitCode
|
-> m ExitCode
|
||||||
run RunOptions{..} runAppState leanAppstate runLogger = do
|
run RunOptions{..} runAppState leanAppstate runLogger = do
|
||||||
tmp <- case runBinDir of
|
r <- if or (fmap (maybe False isToolTag) [runGHCVer, runCabalVer, runHLSVer, runStackVer]) || runInstTool'
|
||||||
Just bdir -> do
|
then runRUN runAppState $ do
|
||||||
liftIO $ createDirRecursive' bdir
|
toolchain <- liftE resolveToolchainFull
|
||||||
liftIO $ canonicalizePath bdir
|
tmp <- case runBinDir of
|
||||||
Nothing -> liftIO (getTemporaryDirectory >>= \tmp -> createTempDirectory tmp "ghcup")
|
Just bindir -> do
|
||||||
r <- do
|
liftIO $ createDirRecursive' bindir
|
||||||
addToolsToDir tmp
|
liftIO $ canonicalizePath bindir
|
||||||
|
Nothing -> do
|
||||||
|
d <- liftIO $ predictableTmpDir toolchain
|
||||||
|
liftIO $ createDirRecursive' d
|
||||||
|
liftIO $ canonicalizePath d
|
||||||
|
liftE $ installToolChainFull toolchain tmp
|
||||||
|
pure tmp
|
||||||
|
else runLeanRUN leanAppstate $ do
|
||||||
|
toolchain <- resolveToolchain
|
||||||
|
tmp <- case runBinDir of
|
||||||
|
Just bindir -> do
|
||||||
|
liftIO $ createDirRecursive' bindir
|
||||||
|
liftIO $ canonicalizePath bindir
|
||||||
|
Nothing -> do
|
||||||
|
d <- liftIO $ predictableTmpDir toolchain
|
||||||
|
liftIO $ createDirRecursive' d
|
||||||
|
liftIO $ canonicalizePath d
|
||||||
|
liftE $ installToolChain toolchain tmp
|
||||||
|
pure tmp
|
||||||
case r of
|
case r of
|
||||||
VRight _ -> do
|
VRight tmp -> do
|
||||||
case runCOMMAND of
|
case runCOMMAND of
|
||||||
[] -> do
|
[] -> do
|
||||||
liftIO $ putStr tmp
|
liftIO $ putStr tmp
|
||||||
pure ExitSuccess
|
pure ExitSuccess
|
||||||
(cmd:args) -> do
|
(cmd:args) -> do
|
||||||
newEnv <- liftIO $ addToPath tmp
|
newEnv <- liftIO $ addToPath tmp
|
||||||
#ifndef IS_WINDOWS
|
#ifndef IS_WINDOWS
|
||||||
void $ liftIO $ SPP.executeFile cmd True args (Just newEnv)
|
void $ liftIO $ SPP.executeFile cmd True args (Just newEnv)
|
||||||
pure ExitSuccess
|
pure ExitSuccess
|
||||||
#else
|
#else
|
||||||
r' <- runLeanRUN leanAppstate $ liftE $ lEM @_ @'[ProcessError] $ exec cmd args Nothing (Just newEnv)
|
r' <- runLeanRUN leanAppstate $ liftE $ lEM @_ @'[ProcessError] $ exec cmd args Nothing (Just newEnv)
|
||||||
case r' of
|
case r' of
|
||||||
VRight _ -> pure ExitSuccess
|
VRight _ -> pure ExitSuccess
|
||||||
VLeft e -> do
|
VLeft e -> do
|
||||||
runLogger $ logError $ T.pack $ prettyShow e
|
runLogger $ logError $ T.pack $ prettyShow e
|
||||||
pure $ ExitFailure 28
|
pure $ ExitFailure 28
|
||||||
#endif
|
#endif
|
||||||
VLeft e -> do
|
VLeft e -> do
|
||||||
runLogger $ logError $ T.pack $ prettyShow e
|
runLogger $ logError $ T.pack $ prettyShow e
|
||||||
pure $ ExitFailure 27
|
pure $ ExitFailure 27
|
||||||
|
|
||||||
where
|
where
|
||||||
|
|
||||||
isToolTag :: ToolVersion -> Bool
|
isToolTag :: ToolVersion -> Bool
|
||||||
isToolTag (ToolTag _) = True
|
isToolTag (ToolTag _) = True
|
||||||
isToolTag _ = False
|
isToolTag _ = False
|
||||||
|
|
||||||
-- TODO: doesn't work for cross
|
-- TODO: doesn't work for cross
|
||||||
addToolsToDir tmp
|
resolveToolchainFull :: ( MonadFail m
|
||||||
| or (fmap (maybe False isToolTag) [runGHCVer, runCabalVer, runHLSVer, runStackVer]) || runInstTool' = runRUN runAppState $ do
|
, MonadThrow m
|
||||||
forM_ runGHCVer $ \ver -> do
|
, MonadIO m
|
||||||
|
, MonadCatch m
|
||||||
|
)
|
||||||
|
=> Excepts
|
||||||
|
'[ TagNotFound
|
||||||
|
, NextVerNotFound
|
||||||
|
, NoToolVersionSet
|
||||||
|
] (ResourceT (ReaderT AppState m)) Toolchain
|
||||||
|
resolveToolchainFull = do
|
||||||
|
ghcVer <- forM runGHCVer $ \ver -> do
|
||||||
(v, _) <- liftE $ fromVersion (Just ver) GHC
|
(v, _) <- liftE $ fromVersion (Just ver) GHC
|
||||||
installTool GHC v
|
pure v
|
||||||
setTool GHC v tmp
|
cabalVer <- forM runCabalVer $ \ver -> do
|
||||||
forM_ runCabalVer $ \ver -> do
|
|
||||||
(v, _) <- liftE $ fromVersion (Just ver) Cabal
|
(v, _) <- liftE $ fromVersion (Just ver) Cabal
|
||||||
installTool Cabal v
|
pure v
|
||||||
setTool Cabal v tmp
|
hlsVer <- forM runHLSVer $ \ver -> do
|
||||||
forM_ runHLSVer $ \ver -> do
|
|
||||||
(v, _) <- liftE $ fromVersion (Just ver) HLS
|
(v, _) <- liftE $ fromVersion (Just ver) HLS
|
||||||
installTool HLS v
|
pure v
|
||||||
setTool HLS v tmp
|
stackVer <- forM runStackVer $ \ver -> do
|
||||||
forM_ runStackVer $ \ver -> do
|
|
||||||
(v, _) <- liftE $ fromVersion (Just ver) Stack
|
(v, _) <- liftE $ fromVersion (Just ver) Stack
|
||||||
installTool Stack v
|
pure v
|
||||||
setTool Stack v tmp
|
pure Toolchain{..}
|
||||||
| otherwise = runLeanRUN leanAppstate $ do
|
|
||||||
case runGHCVer of
|
|
||||||
Just (ToolVersion v) ->
|
|
||||||
setTool GHC v tmp
|
|
||||||
Nothing -> pure ()
|
|
||||||
_ -> fail "Internal error"
|
|
||||||
case runCabalVer of
|
|
||||||
Just (ToolVersion v) ->
|
|
||||||
setTool Cabal v tmp
|
|
||||||
Nothing -> pure ()
|
|
||||||
_ -> fail "Internal error"
|
|
||||||
case runHLSVer of
|
|
||||||
Just (ToolVersion v) ->
|
|
||||||
setTool HLS v tmp
|
|
||||||
Nothing -> pure ()
|
|
||||||
_ -> fail "Internal error"
|
|
||||||
case runStackVer of
|
|
||||||
Just (ToolVersion v) ->
|
|
||||||
setTool Stack v tmp
|
|
||||||
Nothing -> pure ()
|
|
||||||
_ -> fail "Internal error"
|
|
||||||
|
|
||||||
installTool tool v = do
|
resolveToolchain = do
|
||||||
isInstalled <- checkIfToolInstalled' tool v
|
ghcVer <- case runGHCVer of
|
||||||
case tool of
|
Just (ToolVersion v) -> pure $ Just v
|
||||||
GHC -> do
|
Nothing -> pure Nothing
|
||||||
unless isInstalled $ when (runInstTool' && isNothing (_tvTarget v)) $ void $ liftE $ installGHCBin
|
_ -> fail "Internal error"
|
||||||
(_tvVersion v)
|
cabalVer <- case runCabalVer of
|
||||||
Nothing
|
Just (ToolVersion v) -> pure $ Just v
|
||||||
False
|
Nothing -> pure Nothing
|
||||||
Cabal -> do
|
_ -> fail "Internal error"
|
||||||
unless isInstalled $ when runInstTool' $ void $ liftE $ installCabalBin
|
hlsVer <- case runHLSVer of
|
||||||
(_tvVersion v)
|
Just (ToolVersion v) -> pure $ Just v
|
||||||
Nothing
|
Nothing -> pure Nothing
|
||||||
False
|
_ -> fail "Internal error"
|
||||||
Stack -> do
|
stackVer <- case runStackVer of
|
||||||
unless isInstalled $ when runInstTool' $ void $ liftE $ installStackBin
|
Just (ToolVersion v) -> pure $ Just v
|
||||||
(_tvVersion v)
|
Nothing -> pure Nothing
|
||||||
Nothing
|
_ -> fail "Internal error"
|
||||||
False
|
pure Toolchain{..}
|
||||||
HLS -> do
|
|
||||||
unless isInstalled $ when runInstTool' $ void $ liftE $ installHLSBin
|
installToolChainFull :: ( MonadFail m
|
||||||
(_tvVersion v)
|
, MonadThrow m
|
||||||
Nothing
|
, MonadIO m
|
||||||
False
|
, MonadCatch m
|
||||||
GHCup -> pure ()
|
)
|
||||||
|
=> Toolchain
|
||||||
|
-> FilePath
|
||||||
|
-> Excepts
|
||||||
|
'[ TagNotFound
|
||||||
|
, NextVerNotFound
|
||||||
|
, NoToolVersionSet
|
||||||
|
, UnknownArchive
|
||||||
|
, TarDirDoesNotExist
|
||||||
|
, ProcessError
|
||||||
|
, NotInstalled
|
||||||
|
, NoDownload
|
||||||
|
, GPGError
|
||||||
|
, DownloadFailed
|
||||||
|
, DirNotEmpty
|
||||||
|
, DigestError
|
||||||
|
, BuildFailed
|
||||||
|
, ArchiveResult
|
||||||
|
, AlreadyInstalled
|
||||||
|
, FileAlreadyExistsError
|
||||||
|
, CopyError
|
||||||
|
] (ResourceT (ReaderT AppState m)) ()
|
||||||
|
installToolChainFull Toolchain{..} tmp = do
|
||||||
|
forM_ [(GHC,) <$> ghcVer, (Cabal,) <$> cabalVer, (HLS,) <$> hlsVer, (Stack,) <$> stackVer] $ \mt -> do
|
||||||
|
isInstalled <- maybe (pure False) (\(tool, v) -> lift $ checkIfToolInstalled' tool v) mt
|
||||||
|
case mt of
|
||||||
|
Just (GHC, v) -> do
|
||||||
|
unless isInstalled $ when (runInstTool' && isNothing (_tvTarget v)) $ void $ liftE $ installGHCBin
|
||||||
|
(_tvVersion v)
|
||||||
|
Nothing
|
||||||
|
False
|
||||||
|
setTool GHC v tmp
|
||||||
|
Just (Cabal, v) -> do
|
||||||
|
unless isInstalled $ when runInstTool' $ void $ liftE $ installCabalBin
|
||||||
|
(_tvVersion v)
|
||||||
|
Nothing
|
||||||
|
False
|
||||||
|
setTool Cabal v tmp
|
||||||
|
Just (Stack, v) -> do
|
||||||
|
unless isInstalled $ when runInstTool' $ void $ liftE $ installStackBin
|
||||||
|
(_tvVersion v)
|
||||||
|
Nothing
|
||||||
|
False
|
||||||
|
setTool Stack v tmp
|
||||||
|
Just (HLS, v) -> do
|
||||||
|
unless isInstalled $ when runInstTool' $ void $ liftE $ installHLSBin
|
||||||
|
(_tvVersion v)
|
||||||
|
Nothing
|
||||||
|
False
|
||||||
|
setTool HLS v tmp
|
||||||
|
_ -> pure ()
|
||||||
|
|
||||||
|
installToolChain :: ( MonadFail m
|
||||||
|
, MonadThrow m
|
||||||
|
, MonadIO m
|
||||||
|
, MonadCatch m
|
||||||
|
)
|
||||||
|
=> Toolchain
|
||||||
|
-> FilePath
|
||||||
|
-> Excepts '[NotInstalled] (ReaderT LeanAppState m) ()
|
||||||
|
installToolChain Toolchain{..} tmp = do
|
||||||
|
forM_ [(GHC,) <$> ghcVer, (Cabal,) <$> cabalVer, (HLS,) <$> hlsVer, (Stack,) <$> stackVer] $ \mt -> do
|
||||||
|
case mt of
|
||||||
|
Just (GHC, v) -> setTool GHC v tmp
|
||||||
|
Just (Cabal, v) -> setTool Cabal v tmp
|
||||||
|
Just (Stack, v) -> setTool Stack v tmp
|
||||||
|
Just (HLS, v) -> setTool HLS v tmp
|
||||||
|
_ -> pure ()
|
||||||
|
|
||||||
setTool tool v tmp =
|
setTool tool v tmp =
|
||||||
case tool of
|
case tool of
|
||||||
@@ -360,3 +433,31 @@ run RunOptions{..} runAppState leanAppstate runLogger = do
|
|||||||
envWithNewPath = Map.toList $ Map.insert pathVar newPath envWithoutPath
|
envWithNewPath = Map.toList $ Map.insert pathVar newPath envWithoutPath
|
||||||
liftIO $ setEnv pathVar newPath
|
liftIO $ setEnv pathVar newPath
|
||||||
return envWithNewPath
|
return envWithNewPath
|
||||||
|
|
||||||
|
predictableTmpDir (Toolchain Nothing Nothing Nothing Nothing) =
|
||||||
|
liftIO (getTemporaryDirectory >>= \tmp -> pure (tmp </> "ghcup-none"))
|
||||||
|
predictableTmpDir Toolchain{..} = do
|
||||||
|
tmp <- getTemporaryDirectory
|
||||||
|
pure $ tmp
|
||||||
|
</> ("ghcup-" <> intercalate "_"
|
||||||
|
( maybe [] ( (:[]) . ("ghc-" <>) . T.unpack . tVerToText) ghcVer
|
||||||
|
<> maybe [] ( (:[]) . ("cabal-" <>) . T.unpack . tVerToText) cabalVer
|
||||||
|
<> maybe [] ( (:[]) . ("hls-" <>) . T.unpack . tVerToText) hlsVer
|
||||||
|
<> maybe [] ( (:[]) . ("stack-" <>) . T.unpack . tVerToText) stackVer
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-------------------------
|
||||||
|
--[ Other local types ]--
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
data Toolchain = Toolchain
|
||||||
|
{ ghcVer :: Maybe GHCTargetVersion
|
||||||
|
, cabalVer :: Maybe GHCTargetVersion
|
||||||
|
, hlsVer :: Maybe GHCTargetVersion
|
||||||
|
, stackVer :: Maybe GHCTargetVersion
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
{-# LANGUAGE FlexibleContexts #-}
|
{-# LANGUAGE FlexibleContexts #-}
|
||||||
{-# LANGUAGE DuplicateRecordFields #-}
|
{-# LANGUAGE DuplicateRecordFields #-}
|
||||||
{-# LANGUAGE RankNTypes #-}
|
{-# LANGUAGE RankNTypes #-}
|
||||||
|
{-# LANGUAGE QuasiQuotes #-}
|
||||||
|
|
||||||
module GHCup.OptParse.ToolRequirements where
|
module GHCup.OptParse.ToolRequirements where
|
||||||
|
|
||||||
@@ -11,6 +12,7 @@ module GHCup.OptParse.ToolRequirements where
|
|||||||
import GHCup.Errors
|
import GHCup.Errors
|
||||||
import GHCup.Types
|
import GHCup.Types
|
||||||
import GHCup.Utils.Logger
|
import GHCup.Utils.Logger
|
||||||
|
import GHCup.Utils.String.QQ
|
||||||
|
|
||||||
#if !MIN_VERSION_base(4,13,0)
|
#if !MIN_VERSION_base(4,13,0)
|
||||||
import Control.Monad.Fail ( MonadFail )
|
import Control.Monad.Fail ( MonadFail )
|
||||||
@@ -34,6 +36,41 @@ import System.IO
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
---------------
|
||||||
|
--[ Options ]--
|
||||||
|
---------------
|
||||||
|
|
||||||
|
|
||||||
|
data ToolReqOpts = ToolReqOpts
|
||||||
|
{ tlrRaw :: Bool
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
---------------
|
||||||
|
--[ Parsers ]--
|
||||||
|
---------------
|
||||||
|
|
||||||
|
|
||||||
|
toolReqP :: Parser ToolReqOpts
|
||||||
|
toolReqP =
|
||||||
|
ToolReqOpts
|
||||||
|
<$> switch (short 'r' <> long "raw-format" <> help "machine-parsable format")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--------------
|
||||||
|
--[ Footer ]--
|
||||||
|
--------------
|
||||||
|
|
||||||
|
|
||||||
|
toolReqFooter :: String
|
||||||
|
toolReqFooter = [s|Discussion:
|
||||||
|
Print tool requirements on the current platform.
|
||||||
|
If you want to pass this to your package manage, use '--raw-format'.|]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
---------------------------
|
---------------------------
|
||||||
@@ -66,14 +103,17 @@ toolRequirements :: ( Monad m
|
|||||||
, MonadFail m
|
, MonadFail m
|
||||||
, Alternative m
|
, Alternative m
|
||||||
)
|
)
|
||||||
=> (ReaderT AppState m (VEither ToolRequirementsEffects ()) -> m (VEither ToolRequirementsEffects ()))
|
=> ToolReqOpts
|
||||||
|
-> (ReaderT AppState m (VEither ToolRequirementsEffects ()) -> m (VEither ToolRequirementsEffects ()))
|
||||||
-> (ReaderT LeanAppState m () -> m ())
|
-> (ReaderT LeanAppState m () -> m ())
|
||||||
-> m ExitCode
|
-> m ExitCode
|
||||||
toolRequirements runAppState runLogger = runToolRequirements runAppState (do
|
toolRequirements ToolReqOpts{..} runAppState runLogger = runToolRequirements runAppState (do
|
||||||
GHCupInfo { .. } <- lift getGHCupInfo
|
GHCupInfo { .. } <- lift getGHCupInfo
|
||||||
platform' <- liftE getPlatform
|
platform' <- liftE getPlatform
|
||||||
req <- getCommonRequirements platform' _toolRequirements ?? NoToolRequirements
|
req <- getCommonRequirements platform' _toolRequirements ?? NoToolRequirements
|
||||||
liftIO $ T.hPutStr stdout (prettyRequirements req)
|
if tlrRaw
|
||||||
|
then liftIO $ T.hPutStr stdout (rawRequirements req)
|
||||||
|
else liftIO $ T.hPutStr stdout (prettyRequirements req)
|
||||||
)
|
)
|
||||||
>>= \case
|
>>= \case
|
||||||
VRight _ -> pure ExitSuccess
|
VRight _ -> pure ExitSuccess
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ toSettings options = do
|
|||||||
keepDirs = fromMaybe (fromMaybe (Types.keepDirs defaultSettings) uKeepDirs) optKeepDirs
|
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 (Types.urlSource defaultSettings) uUrlSource) OwnSource optUrlSource
|
urlSource = maybe (fromMaybe (Types.urlSource defaultSettings) uUrlSource) (OwnSource . (:[]) . Right) optUrlSource
|
||||||
noNetwork = fromMaybe (fromMaybe (Types.noNetwork defaultSettings) uNoNetwork) optNoNetwork
|
noNetwork = fromMaybe (fromMaybe (Types.noNetwork defaultSettings) uNoNetwork) optNoNetwork
|
||||||
gpgSetting = fromMaybe (fromMaybe (Types.gpgSetting defaultSettings) uGPGSetting) optGpg
|
gpgSetting = fromMaybe (fromMaybe (Types.gpgSetting defaultSettings) uGPGSetting) optGpg
|
||||||
in (Settings {..}, keyBindings)
|
in (Settings {..}, keyBindings)
|
||||||
@@ -228,14 +228,16 @@ Report bugs at <https://gitlab.haskell.org/haskell/ghcup-hs/issues>|]
|
|||||||
Nuke -> pure ()
|
Nuke -> pure ()
|
||||||
Whereis _ _ -> pure ()
|
Whereis _ _ -> pure ()
|
||||||
DInfo -> pure ()
|
DInfo -> pure ()
|
||||||
ToolRequirements -> pure ()
|
ToolRequirements _ -> pure ()
|
||||||
ChangeLog _ -> pure ()
|
ChangeLog _ -> pure ()
|
||||||
UnSet _ -> pure ()
|
UnSet _ -> pure ()
|
||||||
#if defined(BRICK)
|
#if defined(BRICK)
|
||||||
Interactive -> pure ()
|
Interactive -> pure ()
|
||||||
#endif
|
#endif
|
||||||
-- check for new tools
|
-- check for new tools
|
||||||
_ -> lookupEnv "GHCUP_SKIP_UPDATE_CHECK" >>= \case
|
_
|
||||||
|
| Just False <- optVerbose -> pure ()
|
||||||
|
| otherwise -> lookupEnv "GHCUP_SKIP_UPDATE_CHECK" >>= \case
|
||||||
Nothing -> void . flip runReaderT s' . runE @'[TagNotFound, NextVerNotFound, NoToolVersionSet] $ do
|
Nothing -> void . flip runReaderT s' . runE @'[TagNotFound, NextVerNotFound, NoToolVersionSet] $ do
|
||||||
newTools <- lift checkForUpdates
|
newTools <- lift checkForUpdates
|
||||||
forM_ newTools $ \newTool@(t, l) -> do
|
forM_ newTools $ \newTool@(t, l) -> do
|
||||||
@@ -308,12 +310,12 @@ Report bugs at <https://gitlab.haskell.org/haskell/ghcup-hs/issues>|]
|
|||||||
#ifndef DISABLE_UPGRADE
|
#ifndef DISABLE_UPGRADE
|
||||||
Upgrade uOpts force' -> upgrade uOpts force' dirs runAppState runLogger
|
Upgrade uOpts force' -> upgrade uOpts force' dirs runAppState runLogger
|
||||||
#endif
|
#endif
|
||||||
ToolRequirements -> toolRequirements runAppState runLogger
|
ToolRequirements topts -> toolRequirements topts runAppState runLogger
|
||||||
ChangeLog changelogOpts -> changelog changelogOpts runAppState runLogger
|
ChangeLog changelogOpts -> changelog changelogOpts runAppState runLogger
|
||||||
Nuke -> nuke appState runLogger
|
Nuke -> nuke appState runLogger
|
||||||
Prefetch pfCom -> prefetch pfCom runAppState runLogger
|
Prefetch pfCom -> prefetch pfCom runAppState runLogger
|
||||||
GC gcOpts -> gc gcOpts runAppState runLogger
|
GC gcOpts -> gc gcOpts runAppState runLogger
|
||||||
Run runCommand -> run runCommand runAppState leanAppstate runLogger
|
Run runCommand -> run runCommand appState leanAppstate runLogger
|
||||||
|
|
||||||
case res of
|
case res of
|
||||||
ExitSuccess -> pure ()
|
ExitSuccess -> pure ()
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ constraints: any.Cabal ==3.6.2.0,
|
|||||||
any.StateVar ==1.2.2,
|
any.StateVar ==1.2.2,
|
||||||
any.abstract-deque ==0.3,
|
any.abstract-deque ==0.3,
|
||||||
abstract-deque -usecas,
|
abstract-deque -usecas,
|
||||||
any.aeson ==2.0.2.0,
|
any.aeson ==2.0.3.0,
|
||||||
aeson -bytestring-builder -cffi +ordered-keymap,
|
aeson -cffi +ordered-keymap,
|
||||||
any.aeson-pretty ==0.8.9,
|
any.aeson-pretty ==0.8.9,
|
||||||
aeson-pretty +lib-only,
|
aeson-pretty +lib-only,
|
||||||
any.alex ==3.2.7.1,
|
any.alex ==3.2.7.1,
|
||||||
@@ -25,14 +25,14 @@ constraints: any.Cabal ==3.6.2.0,
|
|||||||
async -bench,
|
async -bench,
|
||||||
any.atomic-primops ==0.8.4,
|
any.atomic-primops ==0.8.4,
|
||||||
atomic-primops -debug,
|
atomic-primops -debug,
|
||||||
any.attoparsec ==0.13.2.5,
|
any.attoparsec ==0.14.4,
|
||||||
attoparsec -developer,
|
attoparsec -developer,
|
||||||
any.base ==4.14.3.0,
|
any.base ==4.14.3.0,
|
||||||
any.base-compat ==0.12.1,
|
any.base-compat ==0.12.1,
|
||||||
any.base-compat-batteries ==0.12.1,
|
any.base-compat-batteries ==0.12.1,
|
||||||
any.base-orphans ==0.8.6,
|
any.base-orphans ==0.8.6,
|
||||||
any.base16-bytestring ==1.0.2.0,
|
any.base16-bytestring ==1.0.2.0,
|
||||||
any.base64-bytestring ==1.1.0.0,
|
any.base64-bytestring ==1.2.1.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,
|
||||||
@@ -69,7 +69,7 @@ constraints: any.Cabal ==3.6.2.0,
|
|||||||
any.cryptohash-sha1 ==0.11.101.0,
|
any.cryptohash-sha1 ==0.11.101.0,
|
||||||
any.cryptohash-sha256 ==0.11.102.1,
|
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.2,
|
||||||
any.data-fix ==0.3.2,
|
any.data-fix ==0.3.2,
|
||||||
any.deepseq ==1.4.4.0,
|
any.deepseq ==1.4.4.0,
|
||||||
any.directory ==1.3.6.0,
|
any.directory ==1.3.6.0,
|
||||||
@@ -82,10 +82,14 @@ constraints: any.Cabal ==3.6.2.0,
|
|||||||
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.fusion-plugin-types ==0.1.0,
|
||||||
any.generic-arbitrary ==0.1.0,
|
any.generic-arbitrary ==0.2.0,
|
||||||
|
any.ghc ==8.10.7,
|
||||||
|
any.ghc-boot ==8.10.7,
|
||||||
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-heap ==8.10.7,
|
||||||
any.ghc-prim ==0.6.1,
|
any.ghc-prim ==0.6.1,
|
||||||
|
any.ghci ==8.10.7,
|
||||||
any.happy ==1.20.0,
|
any.happy ==1.20.0,
|
||||||
any.hashable ==1.4.0.2,
|
any.hashable ==1.4.0.2,
|
||||||
hashable +containers +integer-gmp -random-initial-seed,
|
hashable +containers +integer-gmp -random-initial-seed,
|
||||||
@@ -93,11 +97,12 @@ constraints: any.Cabal ==3.6.2.0,
|
|||||||
any.haskus-utils-types ==1.5.1,
|
any.haskus-utils-types ==1.5.1,
|
||||||
any.haskus-utils-variant ==3.2.1,
|
any.haskus-utils-variant ==3.2.1,
|
||||||
any.heaps ==0.4,
|
any.heaps ==0.4,
|
||||||
|
any.hpc ==0.6.1.0,
|
||||||
any.hsc2hs ==0.68.8,
|
any.hsc2hs ==0.68.8,
|
||||||
hsc2hs -in-ghc-tree,
|
hsc2hs -in-ghc-tree,
|
||||||
any.hspec ==2.7.10,
|
any.hspec ==2.9.4,
|
||||||
any.hspec-core ==2.7.10,
|
any.hspec-core ==2.9.4,
|
||||||
any.hspec-discover ==2.7.10,
|
any.hspec-discover ==2.9.4,
|
||||||
any.hspec-expectations ==0.8.2,
|
any.hspec-expectations ==0.8.2,
|
||||||
any.hspec-golden-aeson ==0.9.0.0,
|
any.hspec-golden-aeson ==0.9.0.0,
|
||||||
any.http-io-streams ==0.1.6.0,
|
any.http-io-streams ==0.1.6.0,
|
||||||
@@ -118,7 +123,7 @@ constraints: any.Cabal ==3.6.2.0,
|
|||||||
libyaml-streamly -no-unicode -system-libyaml,
|
libyaml-streamly -no-unicode -system-libyaml,
|
||||||
any.lockfree-queue ==0.2.3.1,
|
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.2.0,
|
||||||
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,
|
||||||
@@ -134,7 +139,7 @@ constraints: any.Cabal ==3.6.2.0,
|
|||||||
optics-core -explicit-generic-labels,
|
optics-core -explicit-generic-labels,
|
||||||
any.optics-extra ==0.4,
|
any.optics-extra ==0.4,
|
||||||
any.optics-th ==0.4,
|
any.optics-th ==0.4,
|
||||||
any.optparse-applicative ==0.16.1.0,
|
any.optparse-applicative ==0.17.0.0,
|
||||||
optparse-applicative +process,
|
optparse-applicative +process,
|
||||||
any.os-release ==1.0.2.1,
|
any.os-release ==1.0.2.1,
|
||||||
os-release -devel,
|
os-release -devel,
|
||||||
@@ -173,13 +178,14 @@ constraints: any.Cabal ==3.6.2.0,
|
|||||||
any.splitmix ==0.1.0.4,
|
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.1.1,
|
any.streamly ==0.8.2,
|
||||||
streamly -debug -dev -fusion-plugin -has-llvm -inspection -limit-build-mem -no-fusion +opt -streamk -use-c-malloc,
|
streamly -debug -dev -fusion-plugin -has-llvm -inspection -limit-build-mem -no-fusion +opt -streamk -streamly-core -use-c-malloc -use-unliftio,
|
||||||
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,
|
||||||
any.tagged ==0.8.6.1,
|
any.tagged ==0.8.6.1,
|
||||||
tagged +deepseq +transformers,
|
tagged +deepseq +transformers,
|
||||||
|
any.tagsoup ==0.14.8,
|
||||||
any.template-haskell ==2.16.0.0,
|
any.template-haskell ==2.16.0.0,
|
||||||
any.temporary ==1.3,
|
any.temporary ==1.3,
|
||||||
any.terminal-progress-bar ==0.4.1,
|
any.terminal-progress-bar ==0.4.1,
|
||||||
@@ -211,7 +217,7 @@ constraints: any.Cabal ==3.6.2.0,
|
|||||||
any.unix-compat ==0.5.4,
|
any.unix-compat ==0.5.4,
|
||||||
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.16.0,
|
any.unordered-containers ==0.2.17.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,
|
||||||
@@ -219,15 +225,15 @@ constraints: any.Cabal ==3.6.2.0,
|
|||||||
any.uuid-types ==1.0.5,
|
any.uuid-types ==1.0.5,
|
||||||
any.vector ==0.12.3.1,
|
any.vector ==0.12.3.1,
|
||||||
vector +boundschecks -internalchecks -unsafechecks -wall,
|
vector +boundschecks -internalchecks -unsafechecks -wall,
|
||||||
any.versions ==5.0.2,
|
any.versions ==5.0.3,
|
||||||
any.vty ==5.33,
|
any.vty ==5.33,
|
||||||
any.witherable ==0.4.2,
|
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.1,
|
||||||
any.yaml-streamly ==0.12.1,
|
any.yaml-streamly ==0.12.1,
|
||||||
yaml-streamly +no-examples +no-exe,
|
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 2022-02-15T12:16:42Z
|
index-state: hackage.haskell.org 2022-03-15T16:43:02Z
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ constraints: any.Cabal ==3.6.2.0,
|
|||||||
any.StateVar ==1.2.2,
|
any.StateVar ==1.2.2,
|
||||||
any.abstract-deque ==0.3,
|
any.abstract-deque ==0.3,
|
||||||
abstract-deque -usecas,
|
abstract-deque -usecas,
|
||||||
any.aeson ==2.0.2.0,
|
any.aeson ==2.0.3.0,
|
||||||
aeson -bytestring-builder -cffi +ordered-keymap,
|
aeson -cffi +ordered-keymap,
|
||||||
any.aeson-pretty ==0.8.9,
|
any.aeson-pretty ==0.8.9,
|
||||||
aeson-pretty +lib-only,
|
aeson-pretty +lib-only,
|
||||||
any.alex ==3.2.7.1,
|
any.alex ==3.2.7.1,
|
||||||
@@ -25,14 +25,14 @@ constraints: any.Cabal ==3.6.2.0,
|
|||||||
async -bench,
|
async -bench,
|
||||||
any.atomic-primops ==0.8.4,
|
any.atomic-primops ==0.8.4,
|
||||||
atomic-primops -debug,
|
atomic-primops -debug,
|
||||||
any.attoparsec ==0.13.2.5,
|
any.attoparsec ==0.14.4,
|
||||||
attoparsec -developer,
|
attoparsec -developer,
|
||||||
any.base ==4.15.1.0,
|
any.base ==4.15.1.0,
|
||||||
any.base-compat ==0.12.1,
|
any.base-compat ==0.12.1,
|
||||||
any.base-compat-batteries ==0.12.1,
|
any.base-compat-batteries ==0.12.1,
|
||||||
any.base-orphans ==0.8.6,
|
any.base-orphans ==0.8.6,
|
||||||
any.base16-bytestring ==1.0.2.0,
|
any.base16-bytestring ==1.0.2.0,
|
||||||
any.base64-bytestring ==1.1.0.0,
|
any.base64-bytestring ==1.2.1.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,
|
||||||
@@ -69,7 +69,7 @@ constraints: any.Cabal ==3.6.2.0,
|
|||||||
any.cryptohash-sha1 ==0.11.101.0,
|
any.cryptohash-sha1 ==0.11.101.0,
|
||||||
any.cryptohash-sha256 ==0.11.102.1,
|
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.2,
|
||||||
any.data-fix ==0.3.2,
|
any.data-fix ==0.3.2,
|
||||||
any.deepseq ==1.4.5.0,
|
any.deepseq ==1.4.5.0,
|
||||||
any.directory ==1.3.6.2,
|
any.directory ==1.3.6.2,
|
||||||
@@ -82,11 +82,15 @@ constraints: any.Cabal ==3.6.2.0,
|
|||||||
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.fusion-plugin-types ==0.1.0,
|
||||||
any.generic-arbitrary ==0.1.0,
|
any.generic-arbitrary ==0.2.0,
|
||||||
|
any.ghc ==9.0.2,
|
||||||
any.ghc-bignum ==1.1,
|
any.ghc-bignum ==1.1,
|
||||||
|
any.ghc-boot ==9.0.2,
|
||||||
any.ghc-boot-th ==9.0.2,
|
any.ghc-boot-th ==9.0.2,
|
||||||
any.ghc-byteorder ==4.11.0.0.10,
|
any.ghc-byteorder ==4.11.0.0.10,
|
||||||
|
any.ghc-heap ==9.0.2,
|
||||||
any.ghc-prim ==0.7.0,
|
any.ghc-prim ==0.7.0,
|
||||||
|
any.ghci ==9.0.2,
|
||||||
any.happy ==1.20.0,
|
any.happy ==1.20.0,
|
||||||
any.hashable ==1.4.0.2,
|
any.hashable ==1.4.0.2,
|
||||||
hashable +containers +integer-gmp -random-initial-seed,
|
hashable +containers +integer-gmp -random-initial-seed,
|
||||||
@@ -94,11 +98,12 @@ constraints: any.Cabal ==3.6.2.0,
|
|||||||
any.haskus-utils-types ==1.5.1,
|
any.haskus-utils-types ==1.5.1,
|
||||||
any.haskus-utils-variant ==3.2.1,
|
any.haskus-utils-variant ==3.2.1,
|
||||||
any.heaps ==0.4,
|
any.heaps ==0.4,
|
||||||
|
any.hpc ==0.6.1.0,
|
||||||
any.hsc2hs ==0.68.8,
|
any.hsc2hs ==0.68.8,
|
||||||
hsc2hs -in-ghc-tree,
|
hsc2hs -in-ghc-tree,
|
||||||
any.hspec ==2.7.10,
|
any.hspec ==2.9.4,
|
||||||
any.hspec-core ==2.7.10,
|
any.hspec-core ==2.9.4,
|
||||||
any.hspec-discover ==2.7.10,
|
any.hspec-discover ==2.9.4,
|
||||||
any.hspec-expectations ==0.8.2,
|
any.hspec-expectations ==0.8.2,
|
||||||
any.hspec-golden-aeson ==0.9.0.0,
|
any.hspec-golden-aeson ==0.9.0.0,
|
||||||
any.http-io-streams ==0.1.6.0,
|
any.http-io-streams ==0.1.6.0,
|
||||||
@@ -118,7 +123,7 @@ constraints: any.Cabal ==3.6.2.0,
|
|||||||
libyaml-streamly -no-unicode -system-libyaml,
|
libyaml-streamly -no-unicode -system-libyaml,
|
||||||
any.lockfree-queue ==0.2.3.1,
|
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.2.0,
|
||||||
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,
|
||||||
@@ -134,7 +139,7 @@ constraints: any.Cabal ==3.6.2.0,
|
|||||||
optics-core -explicit-generic-labels,
|
optics-core -explicit-generic-labels,
|
||||||
any.optics-extra ==0.4,
|
any.optics-extra ==0.4,
|
||||||
any.optics-th ==0.4,
|
any.optics-th ==0.4,
|
||||||
any.optparse-applicative ==0.16.1.0,
|
any.optparse-applicative ==0.17.0.0,
|
||||||
optparse-applicative +process,
|
optparse-applicative +process,
|
||||||
any.os-release ==1.0.2.1,
|
any.os-release ==1.0.2.1,
|
||||||
os-release -devel,
|
os-release -devel,
|
||||||
@@ -173,13 +178,14 @@ constraints: any.Cabal ==3.6.2.0,
|
|||||||
any.splitmix ==0.1.0.4,
|
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.1.1,
|
any.streamly ==0.8.2,
|
||||||
streamly -debug -dev -fusion-plugin -has-llvm -inspection -limit-build-mem -no-fusion +opt -streamk -use-c-malloc,
|
streamly -debug -dev -fusion-plugin -has-llvm -inspection -limit-build-mem -no-fusion +opt -streamk -streamly-core -use-c-malloc -use-unliftio,
|
||||||
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,
|
||||||
any.tagged ==0.8.6.1,
|
any.tagged ==0.8.6.1,
|
||||||
tagged +deepseq +transformers,
|
tagged +deepseq +transformers,
|
||||||
|
any.tagsoup ==0.14.8,
|
||||||
any.template-haskell ==2.17.0.0,
|
any.template-haskell ==2.17.0.0,
|
||||||
any.temporary ==1.3,
|
any.temporary ==1.3,
|
||||||
any.terminal-progress-bar ==0.4.1,
|
any.terminal-progress-bar ==0.4.1,
|
||||||
@@ -211,7 +217,7 @@ constraints: any.Cabal ==3.6.2.0,
|
|||||||
any.unix-compat ==0.5.4,
|
any.unix-compat ==0.5.4,
|
||||||
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.16.0,
|
any.unordered-containers ==0.2.17.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,
|
||||||
@@ -219,15 +225,15 @@ constraints: any.Cabal ==3.6.2.0,
|
|||||||
any.uuid-types ==1.0.5,
|
any.uuid-types ==1.0.5,
|
||||||
any.vector ==0.12.3.1,
|
any.vector ==0.12.3.1,
|
||||||
vector +boundschecks -internalchecks -unsafechecks -wall,
|
vector +boundschecks -internalchecks -unsafechecks -wall,
|
||||||
any.versions ==5.0.2,
|
any.versions ==5.0.3,
|
||||||
any.vty ==5.33,
|
any.vty ==5.33,
|
||||||
any.witherable ==0.4.2,
|
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.1,
|
||||||
any.yaml-streamly ==0.12.1,
|
any.yaml-streamly ==0.12.1,
|
||||||
yaml-streamly +no-examples +no-exe,
|
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 2022-02-15T12:16:42Z
|
index-state: hackage.haskell.org 2022-03-15T16:43:02Z
|
||||||
|
|||||||
@@ -48,12 +48,16 @@ url-source:
|
|||||||
|
|
||||||
## Example 1: Read download info from this location instead
|
## Example 1: Read download info from this location instead
|
||||||
## Accepts file/http/https scheme
|
## Accepts file/http/https scheme
|
||||||
|
## Can also be an array of URLs or an array of 'Either GHCupInfo URL', in
|
||||||
|
## which case they are merged right-biased (overwriting duplicate versions).
|
||||||
# OwnSource: "file:///home/jule/git/ghcup-hs/ghcup-0.0.3.yaml"
|
# OwnSource: "file:///home/jule/git/ghcup-hs/ghcup-0.0.3.yaml"
|
||||||
|
|
||||||
## Example 2: Add custom tarballs to the default downloads, overwriting duplicate versions
|
## Example 2: Add custom tarballs to the default downloads, overwriting duplicate versions.
|
||||||
|
## Can also be an array of 'Either GHCupInfo URL', also see Example 3.
|
||||||
# AddSource:
|
# AddSource:
|
||||||
# Left:
|
# Left:
|
||||||
# toolRequirements: {} # this is ignored
|
# globalTools: {}
|
||||||
|
# toolRequirements: {}
|
||||||
# ghcupDownloads:
|
# ghcupDownloads:
|
||||||
# GHC:
|
# GHC:
|
||||||
# 9.10.2:
|
# 9.10.2:
|
||||||
@@ -66,6 +70,8 @@ url-source:
|
|||||||
# dlSubdir: ghc-7.10.3
|
# dlSubdir: ghc-7.10.3
|
||||||
# dlHash: 01cfbad8dff1e8b34a5fdca8caeaf843b56e36af919e29cd68870d2588563db5
|
# dlHash: 01cfbad8dff1e8b34a5fdca8caeaf843b56e36af919e29cd68870d2588563db5
|
||||||
|
|
||||||
## Example 3: Add a custom download file to the default downloads, overwriting duplicate versions
|
## Example 3: Add multiple custom download files to the default downloads via right-biased merge (overwriting duplicate
|
||||||
|
## versions).
|
||||||
# AddSource:
|
# AddSource:
|
||||||
# Right: "file:///home/jule/git/ghcup-hs/ghcup-custom.yaml"
|
# - Right: "file:///home/jule/git/ghcup-hs/ghcup-prereleases.yaml"
|
||||||
|
# - Right: "file:///home/jule/git/ghcup-hs/ghcup-custom.yaml"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
cabal-version: 3.0
|
cabal-version: 3.0
|
||||||
name: ghcup
|
name: ghcup
|
||||||
version: 0.1.17.5
|
version: 0.1.17.6
|
||||||
license: LGPL-3.0-only
|
license: LGPL-3.0-only
|
||||||
license-file: LICENSE
|
license-file: LICENSE
|
||||||
copyright: Julian Ospald 2020
|
copyright: Julian Ospald 2020
|
||||||
|
|||||||
@@ -121,28 +121,25 @@ getDownloadsF = do
|
|||||||
Settings { urlSource } <- lift getSettings
|
Settings { urlSource } <- lift getSettings
|
||||||
case urlSource of
|
case urlSource of
|
||||||
GHCupURL -> liftE $ getBase ghcupURL
|
GHCupURL -> liftE $ getBase ghcupURL
|
||||||
(OwnSource url) -> liftE $ getBase url
|
(OwnSource exts) -> do
|
||||||
|
ext <- liftE $ mapM (either pure getBase) exts
|
||||||
|
mergeGhcupInfo ext
|
||||||
(OwnSpec av) -> pure av
|
(OwnSpec av) -> pure av
|
||||||
(AddSource (Left ext)) -> do
|
(AddSource exts) -> do
|
||||||
base <- liftE $ getBase ghcupURL
|
base <- liftE $ getBase ghcupURL
|
||||||
pure (mergeGhcupInfo base ext)
|
ext <- liftE $ mapM (either pure getBase) exts
|
||||||
(AddSource (Right uri)) -> do
|
mergeGhcupInfo (base:ext)
|
||||||
base <- liftE $ getBase ghcupURL
|
|
||||||
ext <- liftE $ getBase uri
|
|
||||||
pure (mergeGhcupInfo base ext)
|
|
||||||
|
|
||||||
where
|
where
|
||||||
|
mergeGhcupInfo :: MonadFail m
|
||||||
mergeGhcupInfo :: GHCupInfo -- ^ base to merge with
|
=> [GHCupInfo]
|
||||||
-> GHCupInfo -- ^ extension overwriting the base
|
-> m GHCupInfo
|
||||||
-> GHCupInfo
|
mergeGhcupInfo [] = fail "mergeGhcupInfo: internal error: need at least one GHCupInfo"
|
||||||
mergeGhcupInfo (GHCupInfo tr base base2) (GHCupInfo _ ext ext2) =
|
mergeGhcupInfo xs@(GHCupInfo{}: _) =
|
||||||
let newDownloads = M.mapWithKey (\k a -> case M.lookup k ext of
|
let newDownloads = M.unionsWith (M.unionWith (\_ b2 -> b2)) (_ghcupDownloads <$> xs)
|
||||||
Just a' -> M.union a' a
|
newGlobalTools = M.unionsWith (\_ a2 -> a2 ) (_globalTools <$> xs)
|
||||||
Nothing -> a
|
newToolReqs = M.unionsWith (M.unionWith (\_ b2 -> b2)) (_toolRequirements <$> xs)
|
||||||
) base
|
in pure $ GHCupInfo newToolReqs newDownloads newGlobalTools
|
||||||
newGlobalTools = M.union base2 ext2
|
|
||||||
in GHCupInfo tr newDownloads newGlobalTools
|
|
||||||
|
|
||||||
|
|
||||||
yamlFromCache :: (MonadReader env m, HasDirs env) => URI -> m FilePath
|
yamlFromCache :: (MonadReader env m, HasDirs env) => URI -> m FilePath
|
||||||
|
|||||||
@@ -67,3 +67,9 @@ prettyRequirements Requirements {..} =
|
|||||||
else ""
|
else ""
|
||||||
n = if not . T.null $ _notes then "\n Note: " <> _notes else ""
|
n = if not . T.null $ _notes then "\n Note: " <> _notes else ""
|
||||||
in "System requirements " <> d <> n
|
in "System requirements " <> d <> n
|
||||||
|
|
||||||
|
rawRequirements :: Requirements -> T.Text
|
||||||
|
rawRequirements Requirements {..} =
|
||||||
|
if not . null $ _distroPKGs
|
||||||
|
then T.intercalate " " _distroPKGs
|
||||||
|
else ""
|
||||||
|
|||||||
@@ -286,9 +286,9 @@ instance Pretty TarDir where
|
|||||||
|
|
||||||
-- | Where to fetch GHCupDownloads from.
|
-- | Where to fetch GHCupDownloads from.
|
||||||
data URLSource = GHCupURL
|
data URLSource = GHCupURL
|
||||||
| OwnSource URI
|
| OwnSource [Either GHCupInfo URI] -- ^ complete source list
|
||||||
| OwnSpec GHCupInfo
|
| OwnSpec GHCupInfo
|
||||||
| AddSource (Either GHCupInfo URI) -- ^ merge with GHCupURL
|
| AddSource [Either GHCupInfo URI] -- ^ merge with GHCupURL
|
||||||
deriving (GHC.Generic, Show)
|
deriving (GHC.Generic, Show)
|
||||||
|
|
||||||
instance NFData URLSource
|
instance NFData URLSource
|
||||||
|
|||||||
@@ -79,6 +79,38 @@ instance FromJSON Tag where
|
|||||||
instance ToJSON URI where
|
instance ToJSON URI where
|
||||||
toJSON = toJSON . E.decodeUtf8With E.lenientDecode . serializeURIRef'
|
toJSON = toJSON . E.decodeUtf8With E.lenientDecode . serializeURIRef'
|
||||||
|
|
||||||
|
instance FromJSON URLSource where
|
||||||
|
parseJSON v =
|
||||||
|
parseGHCupURL v
|
||||||
|
<|> parseOwnSourceLegacy v
|
||||||
|
<|> parseOwnSourceNew1 v
|
||||||
|
<|> parseOwnSourceNew2 v
|
||||||
|
<|> parseOwnSpec v
|
||||||
|
<|> legacyParseAddSource v
|
||||||
|
<|> newParseAddSource v
|
||||||
|
where
|
||||||
|
parseOwnSourceLegacy = withObject "URLSource" $ \o -> do
|
||||||
|
r :: URI <- o .: "OwnSource"
|
||||||
|
pure (OwnSource [Right r])
|
||||||
|
parseOwnSourceNew1 = withObject "URLSource" $ \o -> do
|
||||||
|
r :: [URI] <- o .: "OwnSource"
|
||||||
|
pure (OwnSource (fmap Right r))
|
||||||
|
parseOwnSourceNew2 = withObject "URLSource" $ \o -> do
|
||||||
|
r :: [Either GHCupInfo URI] <- o .: "OwnSource"
|
||||||
|
pure (OwnSource r)
|
||||||
|
parseOwnSpec = withObject "URLSource" $ \o -> do
|
||||||
|
r :: GHCupInfo <- o .: "OwnSpec"
|
||||||
|
pure (OwnSpec r)
|
||||||
|
parseGHCupURL = withObject "URLSource" $ \o -> do
|
||||||
|
_ :: [Value] <- o .: "GHCupURL"
|
||||||
|
pure GHCupURL
|
||||||
|
legacyParseAddSource = withObject "URLSource" $ \o -> do
|
||||||
|
r :: Either GHCupInfo URI <- o .: "AddSource"
|
||||||
|
pure (AddSource [r])
|
||||||
|
newParseAddSource = withObject "URLSource" $ \o -> do
|
||||||
|
r :: [Either GHCupInfo URI] <- o .: "AddSource"
|
||||||
|
pure (AddSource r)
|
||||||
|
|
||||||
instance FromJSON URI where
|
instance FromJSON URI where
|
||||||
parseJSON = withText "URL" $ \t ->
|
parseJSON = withText "URL" $ \t ->
|
||||||
case parseURI strictURIParserOptions (encodeUtf8 t) of
|
case parseURI strictURIParserOptions (encodeUtf8 t) of
|
||||||
@@ -314,7 +346,7 @@ deriveJSON defaultOptions { fieldLabelModifier = removeLensFieldLabel } ''Requir
|
|||||||
deriveJSON defaultOptions { fieldLabelModifier = removeLensFieldLabel } ''DownloadInfo
|
deriveJSON defaultOptions { fieldLabelModifier = removeLensFieldLabel } ''DownloadInfo
|
||||||
deriveJSON defaultOptions { fieldLabelModifier = removeLensFieldLabel } ''VersionInfo
|
deriveJSON defaultOptions { fieldLabelModifier = removeLensFieldLabel } ''VersionInfo
|
||||||
deriveJSON defaultOptions { fieldLabelModifier = removeLensFieldLabel } ''GHCupInfo
|
deriveJSON defaultOptions { fieldLabelModifier = removeLensFieldLabel } ''GHCupInfo
|
||||||
deriveJSON defaultOptions { sumEncoding = ObjectWithSingleField } ''URLSource
|
deriveToJSON defaultOptions { sumEncoding = ObjectWithSingleField } ''URLSource
|
||||||
deriveJSON defaultOptions { sumEncoding = ObjectWithSingleField } ''Key
|
deriveJSON defaultOptions { sumEncoding = ObjectWithSingleField } ''Key
|
||||||
deriveJSON defaultOptions { fieldLabelModifier = \str' -> maybe str' T.unpack . T.stripPrefix (T.pack "k-") . T.pack . kebab $ str' } ''UserKeyBindings
|
deriveJSON defaultOptions { fieldLabelModifier = \str' -> maybe str' T.unpack . T.stripPrefix (T.pack "k-") . T.pack . kebab $ str' } ''UserKeyBindings
|
||||||
deriveJSON defaultOptions { fieldLabelModifier = \str' -> maybe str' T.unpack . T.stripPrefix (T.pack "u-") . T.pack . kebab $ str' } ''UserSettings
|
deriveJSON defaultOptions { fieldLabelModifier = \str' -> maybe str' T.unpack . T.stripPrefix (T.pack "u-") . T.pack . kebab $ str' } ''UserSettings
|
||||||
|
|||||||
@@ -339,13 +339,15 @@ useXDG = isJust <$> lookupEnv "GHCUP_USE_XDG_DIRS"
|
|||||||
relativeSymlink :: FilePath -- ^ the path in which to create the symlink
|
relativeSymlink :: FilePath -- ^ the path in which to create the symlink
|
||||||
-> FilePath -- ^ the symlink destination
|
-> FilePath -- ^ the symlink destination
|
||||||
-> FilePath
|
-> FilePath
|
||||||
relativeSymlink p1 p2 =
|
relativeSymlink p1 p2
|
||||||
let d1 = splitDirectories p1
|
| isWindows = p2 -- windows quickly gets into MAX_PATH issues so we don't care about relative symlinks
|
||||||
d2 = splitDirectories p2
|
| otherwise =
|
||||||
common = takeWhile (\(x, y) -> x == y) $ zip d1 d2
|
let d1 = splitDirectories p1
|
||||||
cPrefix = drop (length common) d1
|
d2 = splitDirectories p2
|
||||||
in joinPath (replicate (length cPrefix) "..")
|
common = takeWhile (\(x, y) -> x == y) $ zip d1 d2
|
||||||
<> joinPath ([pathSeparator] : drop (length common) d2)
|
cPrefix = drop (length common) d1
|
||||||
|
in joinPath (replicate (length cPrefix) "..")
|
||||||
|
<> joinPath ([pathSeparator] : drop (length common) d2)
|
||||||
|
|
||||||
|
|
||||||
cleanupTrash :: ( MonadIO m
|
cleanupTrash :: ( MonadIO m
|
||||||
|
|||||||
@@ -181,6 +181,48 @@ _done() {
|
|||||||
exit 0
|
exit 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# @FUNCTION: posix_realpath
|
||||||
|
# @USAGE: <file>
|
||||||
|
# @DESCRIPTION:
|
||||||
|
# Portably gets the realpath and prints it to stdout.
|
||||||
|
# This was initially inspired by
|
||||||
|
# https://gist.github.com/tvlooy/cbfbdb111a4ebad8b93e
|
||||||
|
# and
|
||||||
|
# https://stackoverflow.com/a/246128
|
||||||
|
#
|
||||||
|
# If the file does not exist, just prints it appended to the current directory.
|
||||||
|
# @STDOUT: realpath of the given file
|
||||||
|
posix_realpath() {
|
||||||
|
[ -z "$1" ] && die "Internal error: no argument given to posix_realpath"
|
||||||
|
current_loop=0
|
||||||
|
max_loops=50
|
||||||
|
mysource=$1
|
||||||
|
|
||||||
|
while [ -h "${mysource}" ]; do
|
||||||
|
current_loop=$((current_loop+1))
|
||||||
|
mydir="$( cd -P "$( dirname "${mysource}" )" > /dev/null 2>&1 && pwd )"
|
||||||
|
mysource="$(readlink "${mysource}")"
|
||||||
|
[ "${mysource%${mysource#?}}"x != '/x' ] && mysource="${mydir}/${mysource}"
|
||||||
|
|
||||||
|
if [ ${current_loop} -gt ${max_loops} ] ; then
|
||||||
|
(>&2 echo "${1}: Too many levels of symbolic links")
|
||||||
|
echo "$1"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
mydir="$( cd -P "$( dirname "${mysource}" )" > /dev/null 2>&1 && pwd )"
|
||||||
|
|
||||||
|
# TODO: better distinguish between "does not exist" and "permission denied"
|
||||||
|
if [ -z "${mydir}" ] ; then
|
||||||
|
(>&2 echo "${1}: Permission denied")
|
||||||
|
echo "$(pwd)/$1"
|
||||||
|
else
|
||||||
|
echo "${mydir%/}/$(basename "${mysource}")"
|
||||||
|
fi
|
||||||
|
|
||||||
|
unset current_loop max_loops mysource mydir
|
||||||
|
}
|
||||||
|
|
||||||
download_ghcup() {
|
download_ghcup() {
|
||||||
|
|
||||||
case "${plat}" in
|
case "${plat}" in
|
||||||
@@ -427,23 +469,23 @@ adjust_bashrc() {
|
|||||||
;;
|
;;
|
||||||
fish)
|
fish)
|
||||||
mkdir -p "${GHCUP_PROFILE_FILE%/*}"
|
mkdir -p "${GHCUP_PROFILE_FILE%/*}"
|
||||||
sed -i -e '/# ghcup-env$/ s/^#*/#/' "${GHCUP_PROFILE_FILE}"
|
sed -i -e '/# ghcup-env$/ s/^#*/#/' "$(posix_realpath "${GHCUP_PROFILE_FILE}")"
|
||||||
case $1 in
|
case $1 in
|
||||||
1)
|
1)
|
||||||
echo "set -q GHCUP_INSTALL_BASE_PREFIX[1]; or set GHCUP_INSTALL_BASE_PREFIX \$HOME ; set -gx PATH \$HOME/.cabal/bin $GHCUP_BIN \$PATH # ghcup-env" >> "${GHCUP_PROFILE_FILE}"
|
printf "\n%s" "set -q GHCUP_INSTALL_BASE_PREFIX[1]; or set GHCUP_INSTALL_BASE_PREFIX \$HOME ; set -gx PATH \$HOME/.cabal/bin $GHCUP_BIN \$PATH # ghcup-env" >> "${GHCUP_PROFILE_FILE}"
|
||||||
;;
|
;;
|
||||||
2)
|
2)
|
||||||
echo "set -q GHCUP_INSTALL_BASE_PREFIX[1]; or set GHCUP_INSTALL_BASE_PREFIX \$HOME ; set -gx PATH \$HOME/.cabal/bin \$PATH $GHCUP_BIN # ghcup-env" >> "${GHCUP_PROFILE_FILE}"
|
printf "\n%s" "set -q GHCUP_INSTALL_BASE_PREFIX[1]; or set GHCUP_INSTALL_BASE_PREFIX \$HOME ; set -gx PATH \$HOME/.cabal/bin \$PATH $GHCUP_BIN # ghcup-env" >> "${GHCUP_PROFILE_FILE}"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
;;
|
;;
|
||||||
bash)
|
bash)
|
||||||
sed -i -e '/# ghcup-env$/ s/^#*/#/' "${GHCUP_PROFILE_FILE}"
|
sed -i -e '/# ghcup-env$/ s/^#*/#/' "$(posix_realpath "${GHCUP_PROFILE_FILE}")"
|
||||||
echo "[ -f \"${GHCUP_DIR}/env\" ] && source \"${GHCUP_DIR}/env\" # ghcup-env" >> "${GHCUP_PROFILE_FILE}"
|
printf "\n%s" "[ -f \"${GHCUP_DIR}/env\" ] && source \"${GHCUP_DIR}/env\" # ghcup-env" >> "${GHCUP_PROFILE_FILE}"
|
||||||
case "${plat}" in
|
case "${plat}" in
|
||||||
"Darwin"|"darwin")
|
"Darwin"|"darwin")
|
||||||
if ! grep -q "ghcup-env" "${HOME}/.bash_profile" ; then
|
if ! grep -q "ghcup-env" "${HOME}/.bash_profile" ; then
|
||||||
echo "[[ -f ~/.bashrc ]] && source ~/.bashrc # ghcup-env" >> "${HOME}/.bash_profile"
|
printf "\n%s" "[[ -f ~/.bashrc ]] && source ~/.bashrc # ghcup-env" >> "${HOME}/.bash_profile"
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
MSYS*|MINGW*)
|
MSYS*|MINGW*)
|
||||||
@@ -457,8 +499,8 @@ adjust_bashrc() {
|
|||||||
;;
|
;;
|
||||||
|
|
||||||
zsh)
|
zsh)
|
||||||
sed -i -e '/# ghcup-env$/ s/^#*/#/' "${GHCUP_PROFILE_FILE}"
|
sed -i -e '/# ghcup-env$/ s/^#*/#/' "$(posix_realpath "${GHCUP_PROFILE_FILE}")"
|
||||||
echo "[ -f \"${GHCUP_DIR}/env\" ] && source \"${GHCUP_DIR}/env\" # ghcup-env" >> "${GHCUP_PROFILE_FILE}"
|
printf "\n%s" "[ -f \"${GHCUP_DIR}/env\" ] && source \"${GHCUP_DIR}/env\" # ghcup-env" >> "${GHCUP_PROFILE_FILE}"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
echo
|
echo
|
||||||
|
|||||||
Reference in New Issue
Block a user