Compare commits

..

17 Commits

Author SHA1 Message Date
92bd333552 Fix double appstate 2022-03-18 17:47:49 +01:00
70a451b63e Prepare 0.1.17.6 2022-03-18 17:47:49 +01:00
cfe6c47cd7 Fix max path issues on windows with 'ghcup run' 2022-03-18 17:47:49 +01:00
8eeb32c495 Overhaul metadata merging and add 'ghcup config add-release-channel URI' 2022-03-18 17:47:49 +01:00
fdcd6822c4 Don't do update check on --no-verbose 2022-03-18 17:47:49 +01:00
71390c84da Apply hlint 2022-03-18 17:47:48 +01:00
84d01b1091 Don't do padding for --raw-format 2022-03-18 17:47:40 +01:00
8f9faaa39e Fix appending on profile file if there's no trailing newline
Fixes #333
2022-03-18 17:33:08 +01:00
0898244b2a Preserve symlinks when sedding profile file
Fixes #332
2022-03-18 17:32:37 +01:00
0c70feb09c Fix rather humongous bug in 'ghcup list' 2022-03-17 20:04:59 +01:00
f9a38e616d Add --raw-format to 'tool-requirements' subcommand 2022-03-17 15:05:18 +01:00
e511fc3c0a Fix predictable /tmp dirs so ghcup gc -t fires 2022-03-16 23:15:09 +01:00
3ff670134c FREEZE! 2022-03-15 22:51:35 +01:00
4c0160bb28 Merge branch 'issue-330' 2022-03-14 11:49:40 +01:00
c1e0baedd3 Merge branch 'issue-329' 2022-03-14 11:49:33 +01:00
604a6fc92b Fix bug with isolated installation of not previously installed versions
It would error out trying to set the version.
2022-03-14 00:36:08 +01:00
8c205fd18c Add --no-set to install commands, fixes #330
This also slightly changes the default for
'ghcup install cabal/stack/hls'... instead of
only setting the installed version if it's the latest,
we always set it. So the default is `--set`.

For GHC, the default is `--no-set`.
2022-03-13 22:48:45 +01:00
21 changed files with 425 additions and 235 deletions

View File

@@ -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

View File

@@ -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)
@@ -113,8 +113,8 @@ data Command
opts :: Parser Options opts :: Parser Options
opts = opts =
Options Options
<$> invertableSwitch "verbose" 'v' False (help "Enable verbosity (default: disabled)") <$> invertableSwitch "verbose" (Just 'v') False (help "Enable verbosity (default: disabled)")
<*> invertableSwitch "cache" 'c' False (help "Cache downloads in ~/.ghcup/cache (default: disabled)") <*> invertableSwitch "cache" (Just '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 (option auto (long "metadata-caching" <> help "How long the yaml metadata caching interval is (in seconds), 0 to disable" <> internal))
<*> optional <*> optional
(option (option
@@ -127,7 +127,7 @@ opts =
<> completer fileUri <> completer fileUri
) )
) )
<*> (fmap . fmap) not (invertableSwitch "verify" 'n' True (help "Disable tarball checksum verification (default: enabled)")) <*> (fmap . fmap) not (invertableSwitch "verify" (Just 'n') True (help "Disable tarball checksum verification (default: enabled)"))
<*> optional (option <*> optional (option
(eitherReader keepOnParser) (eitherReader keepOnParser)
( long "keep" ( long "keep"
@@ -153,7 +153,7 @@ opts =
#endif #endif
<> hidden <> hidden
)) ))
<*> invertableSwitch "offline" 'o' False (help "Don't do any network calls, trying cached assets and failing if missing.") <*> invertableSwitch "offline" (Just 'o') False (help "Don't do any network calls, trying cached assets and failing if missing.")
<*> optional (option <*> optional (option
(eitherReader gpgParser) (eitherReader gpgParser)
( long "gpg" ( long "gpg"
@@ -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

View File

@@ -138,7 +138,7 @@ versionArgument criteria tool = argument (eitherReader tVersionEither) (metavar
-- the help is shown only for --no-recursive. -- the help is shown only for --no-recursive.
invertableSwitch invertableSwitch
:: String -- ^ long option :: String -- ^ long option
-> Char -- ^ short option for the non-default option -> Maybe Char -- ^ short option for the non-default option
-> Bool -- ^ is switch enabled by default? -> Bool -- ^ is switch enabled by default?
-> Mod FlagFields Bool -- ^ option modifier -> Mod FlagFields Bool -- ^ option modifier
-> Parser (Maybe Bool) -> Parser (Maybe Bool)
@@ -149,14 +149,14 @@ invertableSwitch longopt shortopt defv optmod = invertableSwitch' longopt shorto
-- | Allows providing option modifiers for both --foo and --no-foo. -- | Allows providing option modifiers for both --foo and --no-foo.
invertableSwitch' invertableSwitch'
:: String -- ^ long option (eg "foo") :: String -- ^ long option (eg "foo")
-> Char -- ^ short option for the non-default option -> Maybe Char -- ^ short option for the non-default option
-> Bool -- ^ is switch enabled by default? -> Bool -- ^ is switch enabled by default?
-> Mod FlagFields Bool -- ^ option modifier for --foo -> Mod FlagFields Bool -- ^ option modifier for --foo
-> Mod FlagFields Bool -- ^ option modifier for --no-foo -> Mod FlagFields Bool -- ^ option modifier for --no-foo
-> Parser (Maybe Bool) -> Parser (Maybe Bool)
invertableSwitch' longopt shortopt defv enmod dismod = optional invertableSwitch' longopt shortopt defv enmod dismod = optional
( flag' True ( enmod <> long longopt <> if defv then mempty else short shortopt) ( flag' True ( enmod <> long longopt <> if defv then mempty else maybe mempty short shortopt)
<|> flag' False (dismod <> long nolongopt <> if defv then short shortopt else mempty) <|> flag' False (dismod <> long nolongopt <> if defv then maybe mempty short shortopt else mempty)
) )
where where
nolongopt = "no-" ++ longopt nolongopt = "no-" ++ longopt

View File

@@ -234,12 +234,7 @@ ghcCompileOpts =
) )
) )
<*> many (argument str (metavar "CONFIGURE_ARGS" <> help "Additional arguments to configure, prefix with '-- ' (longopts)")) <*> many (argument str (metavar "CONFIGURE_ARGS" <> help "Additional arguments to configure, prefix with '-- ' (longopts)"))
<*> flag <*> fmap (fromMaybe False) (invertableSwitch "set" Nothing False (help "Set as active version after install"))
False
True
(long "set" <> help
"Set as active version after install"
)
<*> optional <*> optional
(option (option
(eitherReader (eitherReader
@@ -300,12 +295,7 @@ hlsCompileOpts =
<> (completer $ listCompleter $ fmap show ([1..12] :: [Int])) <> (completer $ listCompleter $ fmap show ([1..12] :: [Int]))
) )
) )
<*> flag <*> fmap (fromMaybe True) (invertableSwitch "set" Nothing True (help "Don't set as active version after install"))
False
True
(long "set" <> help
"Set as active version after install"
)
<*> optional <*> optional
(option (option
(eitherReader (eitherReader

View File

@@ -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

View File

@@ -197,12 +197,8 @@ installOpts tool =
) )
<|> pure (Nothing, Nothing) <|> pure (Nothing, Nothing)
) )
<*> flag <*> fmap (fromMaybe setDefault) (invertableSwitch "set" Nothing setDefault
False (help $ if not setDefault then "Set as active version after install" else "Don't set as active version after install"))
True
(long "set" <> help
"Set as active version after install"
)
<*> optional <*> optional
(option (option
(eitherReader isolateParser) (eitherReader isolateParser)
@@ -215,6 +211,11 @@ installOpts tool =
) )
<*> switch <*> switch
(short 'f' <> long "force" <> help "Force install") (short 'f' <> long "force" <> help "Force install")
where
setDefault = case tool of
Nothing -> False
Just GHC -> False
Just _ -> True
@@ -397,7 +398,7 @@ install installCommand settings getAppState' runLogger = case installCommand of
isolateDir isolateDir
forceInstall forceInstall
) )
$ when instSet $ void $ setGHC v SetGHCOnly Nothing $ when instSet $ when (isNothing isolateDir) $ void $ setGHC v SetGHCOnly Nothing
pure vi pure vi
Just uri -> do Just uri -> do
runInstGHC s'{ settings = settings {noVerify = True}} instPlatform $ do runInstGHC s'{ settings = settings {noVerify = True}} instPlatform $ do
@@ -408,7 +409,7 @@ install installCommand settings getAppState' runLogger = case installCommand of
isolateDir isolateDir
forceInstall forceInstall
) )
$ when instSet $ void $ setGHC v SetGHCOnly Nothing $ when instSet $ when (isNothing isolateDir) $ void $ setGHC v SetGHCOnly Nothing
pure vi pure vi
) )
>>= \case >>= \case
@@ -468,7 +469,7 @@ install installCommand settings getAppState' runLogger = case installCommand of
v v
isolateDir isolateDir
forceInstall forceInstall
) $ when instSet $ void $ setCabal v ) $ when instSet $ when (isNothing isolateDir) $ void $ setCabal v
pure vi pure vi
Just uri -> do Just uri -> do
runInstTool s'{ settings = settings { noVerify = True}} instPlatform $ do runInstTool s'{ settings = settings { noVerify = True}} instPlatform $ do
@@ -478,7 +479,7 @@ install installCommand settings getAppState' runLogger = case installCommand of
v v
isolateDir isolateDir
forceInstall forceInstall
) $ when instSet $ void $ setCabal v ) $ when instSet $ when (isNothing isolateDir) $ void $ setCabal v
pure vi pure vi
) )
>>= \case >>= \case
@@ -519,7 +520,7 @@ install installCommand settings getAppState' runLogger = case installCommand of
v v
isolateDir isolateDir
forceInstall forceInstall
) $ when instSet $ void $ setHLS v SetHLSOnly Nothing ) $ when instSet $ when (isNothing isolateDir) $ void $ setHLS v SetHLSOnly Nothing
pure vi pure vi
Just uri -> do Just uri -> do
runInstTool s'{ settings = settings { noVerify = True}} instPlatform $ do runInstTool s'{ settings = settings { noVerify = True}} instPlatform $ do
@@ -530,7 +531,7 @@ install installCommand settings getAppState' runLogger = case installCommand of
v v
isolateDir isolateDir
forceInstall forceInstall
) $ when instSet $ void $ setHLS v SetHLSOnly Nothing ) $ when instSet $ when (isNothing isolateDir) $ void $ setHLS v SetHLSOnly Nothing
pure vi pure vi
) )
>>= \case >>= \case
@@ -579,7 +580,7 @@ install installCommand settings getAppState' runLogger = case installCommand of
v v
isolateDir isolateDir
forceInstall forceInstall
) $ when instSet $ void $ setStack v ) $ when instSet $ when (isNothing isolateDir) $ void $ setStack v
pure vi pure vi
Just uri -> do Just uri -> do
runInstTool s'{ settings = settings { noVerify = True}} instPlatform $ do runInstTool s'{ settings = settings { noVerify = True}} instPlatform $ do
@@ -589,7 +590,7 @@ install installCommand settings getAppState' runLogger = case installCommand of
v v
isolateDir isolateDir
forceInstall forceInstall
) $ when instSet $ void $ setStack v ) $ when instSet $ when (isNothing isolateDir) $ void $ setStack v
pure vi pure vi
) )
>>= \case >>= \case

View File

@@ -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 =

View File

@@ -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
@@ -187,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'
@@ -212,52 +214,77 @@ 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 = runE @RunEffects ( do run RunOptions{..} runAppState leanAppstate runLogger = do
toolchain <- Excepts resolveToolchain r <- if or (fmap (maybe False isToolTag) [runGHCVer, runCabalVer, runHLSVer, runStackVer]) || runInstTool'
tmp <- case runBinDir of then runRUN runAppState $ do
Just bindir -> do toolchain <- liftE resolveToolchainFull
liftIO $ createDirRecursive' bindir tmp <- case runBinDir of
liftIO $ canonicalizePath bindir Just bindir -> do
Nothing -> do liftIO $ createDirRecursive' bindir
d <- liftIO $ predictableTmpDir toolchain liftIO $ canonicalizePath bindir
liftIO $ createDirRecursive' d Nothing -> do
liftIO $ canonicalizePath d d <- liftIO $ predictableTmpDir toolchain
Excepts $ installToolChain toolchain tmp liftIO $ createDirRecursive' d
pure tmp liftIO $ canonicalizePath d
) >>= \case liftE $ installToolChainFull toolchain tmp
VRight tmp -> do pure tmp
case runCOMMAND of else runLeanRUN leanAppstate $ do
[] -> do toolchain <- resolveToolchain
liftIO $ putStr tmp tmp <- case runBinDir of
pure ExitSuccess Just bindir -> do
(cmd:args) -> do liftIO $ createDirRecursive' bindir
newEnv <- liftIO $ addToPath tmp liftIO $ canonicalizePath bindir
Nothing -> do
d <- liftIO $ predictableTmpDir toolchain
liftIO $ createDirRecursive' d
liftIO $ canonicalizePath d
liftE $ installToolChain toolchain tmp
pure tmp
case r of
VRight tmp -> do
case runCOMMAND of
[] -> do
liftIO $ putStr tmp
pure ExitSuccess
(cmd:args) -> do
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
resolveToolchain resolveToolchainFull :: ( MonadFail m
| or (fmap (maybe False isToolTag) [runGHCVer, runCabalVer, runHLSVer, runStackVer]) || runInstTool' = runRUN runAppState $ do , MonadThrow m
, MonadIO m
, MonadCatch m
)
=> Excepts
'[ TagNotFound
, NextVerNotFound
, NoToolVersionSet
] (ResourceT (ReaderT AppState m)) Toolchain
resolveToolchainFull = do
ghcVer <- forM runGHCVer $ \ver -> do ghcVer <- forM runGHCVer $ \ver -> do
(v, _) <- liftE $ fromVersion (Just ver) GHC (v, _) <- liftE $ fromVersion (Just ver) GHC
pure v pure v
@@ -271,7 +298,8 @@ run RunOptions{..} runAppState leanAppstate runLogger = runE @RunEffects ( do
(v, _) <- liftE $ fromVersion (Just ver) Stack (v, _) <- liftE $ fromVersion (Just ver) Stack
pure v pure v
pure Toolchain{..} pure Toolchain{..}
| otherwise = runLeanRUN leanAppstate $ do
resolveToolchain = do
ghcVer <- case runGHCVer of ghcVer <- case runGHCVer of
Just (ToolVersion v) -> pure $ Just v Just (ToolVersion v) -> pure $ Just v
Nothing -> pure Nothing Nothing -> pure Nothing
@@ -290,8 +318,33 @@ run RunOptions{..} runAppState leanAppstate runLogger = runE @RunEffects ( do
_ -> fail "Internal error" _ -> fail "Internal error"
pure Toolchain{..} pure Toolchain{..}
installToolChain Toolchain{..} tmp installToolChainFull :: ( MonadFail m
| or (fmap (maybe False isToolTag) [runGHCVer, runCabalVer, runHLSVer, runStackVer]) || runInstTool' = runRUN runAppState $ do , MonadThrow m
, MonadIO m
, MonadCatch m
)
=> 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 forM_ [(GHC,) <$> ghcVer, (Cabal,) <$> cabalVer, (HLS,) <$> hlsVer, (Stack,) <$> stackVer] $ \mt -> do
isInstalled <- maybe (pure False) (\(tool, v) -> lift $ checkIfToolInstalled' tool v) mt isInstalled <- maybe (pure False) (\(tool, v) -> lift $ checkIfToolInstalled' tool v) mt
case mt of case mt of
@@ -320,7 +373,16 @@ run RunOptions{..} runAppState leanAppstate runLogger = runE @RunEffects ( do
False False
setTool HLS v tmp setTool HLS v tmp
_ -> pure () _ -> pure ()
| otherwise = runLeanRUN leanAppstate $ do
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 forM_ [(GHC,) <$> ghcVer, (Cabal,) <$> cabalVer, (HLS,) <$> hlsVer, (Stack,) <$> stackVer] $ \mt -> do
case mt of case mt of
Just (GHC, v) -> setTool GHC v tmp Just (GHC, v) -> setTool GHC v tmp
@@ -377,11 +439,12 @@ run RunOptions{..} runAppState leanAppstate runLogger = runE @RunEffects ( do
predictableTmpDir Toolchain{..} = do predictableTmpDir Toolchain{..} = do
tmp <- getTemporaryDirectory tmp <- getTemporaryDirectory
pure $ tmp pure $ tmp
</> ("ghcup" </> ("ghcup-" <> intercalate "_"
<> maybe "" (("_ghc-" <>) . T.unpack . tVerToText) ghcVer ( maybe [] ( (:[]) . ("ghc-" <>) . T.unpack . tVerToText) ghcVer
<> maybe "" (("_cabal-" <>) . T.unpack . tVerToText) cabalVer <> maybe [] ( (:[]) . ("cabal-" <>) . T.unpack . tVerToText) cabalVer
<> maybe "" (("_hls-" <>) . T.unpack . tVerToText) hlsVer <> maybe [] ( (:[]) . ("hls-" <>) . T.unpack . tVerToText) hlsVer
<> maybe "" (("_stack-" <>) . T.unpack . tVerToText) stackVer <> maybe [] ( (:[]) . ("stack-" <>) . T.unpack . tVerToText) stackVer
)
) )

View File

@@ -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

View File

@@ -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 ()

View File

@@ -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

View File

@@ -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

View File

@@ -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"

View File

@@ -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

View File

@@ -468,10 +468,6 @@ installCabalBindist dlinfo ver isoFilepath forceInstall = do
Nothing -> do -- regular install Nothing -> do -- regular install
liftE $ installCabalUnpacked workdir binDir (Just ver) forceInstall liftE $ installCabalUnpacked workdir binDir (Just ver) forceInstall
-- create symlink if this is the latest version for regular installs
cVers <- lift $ fmap rights getInstalledCabals
let lInstCabal = headMay . reverse . sort $ cVers
when (maybe True (ver >=) lInstCabal) $ liftE $ setCabal ver
-- | Install an unpacked cabal distribution.Symbol -- | Install an unpacked cabal distribution.Symbol
installCabalUnpacked :: (MonadCatch m, HasLog env, MonadIO m, MonadReader env m) installCabalUnpacked :: (MonadCatch m, HasLog env, MonadIO m, MonadReader env m)
@@ -626,7 +622,6 @@ installHLSBindist dlinfo ver isoFilepath forceInstall = do
liftE $ runBuildAction tmpUnpack Nothing $ installHLSUnpacked workdir inst ver liftE $ runBuildAction tmpUnpack Nothing $ installHLSUnpacked workdir inst ver
liftE $ setHLS ver SetHLS_XYZ Nothing liftE $ setHLS ver SetHLS_XYZ Nothing
liftE $ installHLSPostInst isoFilepath ver
isLegacyHLSBindist :: FilePath -- ^ Path to the unpacked hls bindist isLegacyHLSBindist :: FilePath -- ^ Path to the unpacked hls bindist
-> IO Bool -> IO Bool
@@ -696,19 +691,6 @@ installHLSUnpackedLegacy path inst mver' forceInstall = do
lift $ chmod_755 destWrapperPath lift $ chmod_755 destWrapperPath
installHLSPostInst :: (MonadReader env m, HasDirs env, HasLog env, MonadIO m, MonadCatch m, MonadMask m, MonadFail m, MonadUnliftIO m)
=> Maybe FilePath
-> Version
-> Excepts '[NotInstalled] m ()
installHLSPostInst isoFilepath ver =
case isoFilepath of
Just _ -> pure ()
Nothing -> do
-- create symlink if this is the latest version in a regular install
hlsVers <- lift $ fmap rights getInstalledHLSs
let lInstHLS = headMay . reverse . sort $ hlsVers
when (maybe True (ver >=) lInstHLS) $ liftE $ setHLS ver SetHLSOnly Nothing
-- | Installs hls binaries @haskell-language-server-\<ghcver\>@ -- | Installs hls binaries @haskell-language-server-\<ghcver\>@
-- into @~\/.ghcup\/bin/@, as well as @haskell-languager-server-wrapper@. -- into @~\/.ghcup\/bin/@, as well as @haskell-languager-server-wrapper@.
@@ -916,8 +898,6 @@ compileHLS targetHLS ghcs jobs ov isolateDir cabalProject cabalProjectLocal patc
liftE $ installHLSUnpackedLegacy installDir binDir (Just installVer) True liftE $ installHLSUnpackedLegacy installDir binDir (Just installVer) True
) )
liftE $ installHLSPostInst isolateDir installVer
pure installVer pure installVer
@@ -1034,11 +1014,6 @@ installStackBindist dlinfo ver isoFilepath forceInstall = do
Nothing -> do -- regular install Nothing -> do -- regular install
liftE $ installStackUnpacked workdir binDir (Just ver) forceInstall liftE $ installStackUnpacked workdir binDir (Just ver) forceInstall
-- create symlink if this is the latest version and a regular install
sVers <- lift $ fmap rights getInstalledStacks
let lInstStack = headMay . reverse . sort $ sVers
when (maybe True (ver >=) lInstStack) $ liftE $ setStack ver
-- | Install an unpacked stack distribution. -- | Install an unpacked stack distribution.
installStackUnpacked :: (MonadReader env m, HasLog env, MonadCatch m, MonadIO m) installStackUnpacked :: (MonadReader env m, HasLog env, MonadCatch m, MonadIO m)

View File

@@ -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

View File

@@ -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 ""

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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