parent
ede6299681
commit
6c95218daf
@ -47,16 +47,16 @@ Common use cases are:
|
|||||||
ghcup list
|
ghcup list
|
||||||
|
|
||||||
# install the recommended GHC version
|
# install the recommended GHC version
|
||||||
ghcup install
|
ghcup install ghc
|
||||||
|
|
||||||
# install a specific GHC version
|
# install a specific GHC version
|
||||||
ghcup install 8.2.2
|
ghcup install ghc 8.2.2
|
||||||
|
|
||||||
# set the currently "active" GHC version
|
# set the currently "active" GHC version
|
||||||
ghcup set 8.4.4
|
ghcup set ghc 8.4.4
|
||||||
|
|
||||||
# install cabal-install
|
# install cabal-install
|
||||||
ghcup install-cabal
|
ghcup install cabal
|
||||||
|
|
||||||
# update ghcup itself
|
# update ghcup itself
|
||||||
ghcup upgrade
|
ghcup upgrade
|
||||||
|
@ -82,11 +82,11 @@ data Options = Options
|
|||||||
}
|
}
|
||||||
|
|
||||||
data Command
|
data Command
|
||||||
= Install InstallOptions
|
= Install (Either InstallCommand InstallOptions)
|
||||||
| InstallCabal InstallOptions
|
| InstallCabalLegacy InstallOptions
|
||||||
| SetGHC SetGHCOptions
|
| Set (Either SetCommand SetOptions)
|
||||||
| List ListOptions
|
| List ListOptions
|
||||||
| Rm RmOptions
|
| Rm (Either RmCommand RmOptions)
|
||||||
| DInfo
|
| DInfo
|
||||||
| Compile CompileCommand
|
| Compile CompileCommand
|
||||||
| Upgrade UpgradeOpts Bool
|
| Upgrade UpgradeOpts Bool
|
||||||
@ -101,13 +101,19 @@ prettyToolVer (ToolVersion v') = T.unpack $ prettyTVer v'
|
|||||||
prettyToolVer (ToolTag t) = show t
|
prettyToolVer (ToolTag t) = show t
|
||||||
|
|
||||||
|
|
||||||
|
data InstallCommand = InstallGHC InstallOptions
|
||||||
|
| InstallCabal InstallOptions
|
||||||
|
|
||||||
data InstallOptions = InstallOptions
|
data InstallOptions = InstallOptions
|
||||||
{ instVer :: Maybe ToolVersion
|
{ instVer :: Maybe ToolVersion
|
||||||
, instPlatform :: Maybe PlatformRequest
|
, instPlatform :: Maybe PlatformRequest
|
||||||
}
|
}
|
||||||
|
|
||||||
data SetGHCOptions = SetGHCOptions
|
data SetCommand = SetGHC SetOptions
|
||||||
{ ghcVer :: Maybe ToolVersion
|
| SetCabal SetOptions
|
||||||
|
|
||||||
|
data SetOptions = SetOptions
|
||||||
|
{ sToolVer :: Maybe ToolVersion
|
||||||
}
|
}
|
||||||
|
|
||||||
data ListOptions = ListOptions
|
data ListOptions = ListOptions
|
||||||
@ -116,6 +122,9 @@ data ListOptions = ListOptions
|
|||||||
, lRawFormat :: Bool
|
, lRawFormat :: Bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data RmCommand = RmGHC RmOptions
|
||||||
|
| RmCabal Version
|
||||||
|
|
||||||
data RmOptions = RmOptions
|
data RmOptions = RmOptions
|
||||||
{ ghcVer :: GHCTargetVersion
|
{ ghcVer :: GHCTargetVersion
|
||||||
}
|
}
|
||||||
@ -213,44 +222,38 @@ com =
|
|||||||
subparser
|
subparser
|
||||||
( command
|
( command
|
||||||
"install"
|
"install"
|
||||||
((info
|
( Install
|
||||||
((Install <$> installOpts) <**> helper)
|
<$> (info
|
||||||
( progDesc "Install or update GHC"
|
(installParser <**> helper)
|
||||||
<> footerDoc (Just $ text installFooter)
|
( progDesc "Install or update GHC/cabal"
|
||||||
)
|
<> footerDoc (Just $ text installToolFooter)
|
||||||
)
|
)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
<> command
|
<> command
|
||||||
"set"
|
"set"
|
||||||
( SetGHC
|
|
||||||
<$> (info
|
|
||||||
(setGHCOpts <**> helper)
|
|
||||||
( progDesc "Set currently active GHC version"
|
|
||||||
<> footerDoc (Just $ text setFooter)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
<> command
|
|
||||||
"rm"
|
|
||||||
( Rm
|
|
||||||
<$> (info (rmOpts <**> helper) (progDesc "Remove a GHC version"))
|
|
||||||
)
|
|
||||||
|
|
||||||
<> command
|
|
||||||
"install-cabal"
|
|
||||||
((info
|
((info
|
||||||
((InstallCabal <$> installOpts) <**> helper)
|
(Set <$> setParser <**> helper)
|
||||||
( progDesc "Install or update cabal"
|
( progDesc "Set currently active GHC/cabal version"
|
||||||
<> footerDoc (Just $ text installCabalFooter)
|
<> footerDoc (Just $ text setFooter)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
<> command
|
||||||
|
"rm"
|
||||||
|
((info
|
||||||
|
(Rm <$> rmParser <**> helper)
|
||||||
|
( progDesc "Remove a GHC/cabal version"
|
||||||
|
<> footerDoc (Just $ text rmFooter)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
<> command
|
<> command
|
||||||
"list"
|
"list"
|
||||||
( List
|
((info (List <$> listOpts <**> helper)
|
||||||
<$> (info (listOpts <**> helper)
|
(progDesc "Show available GHCs and other tools")
|
||||||
(progDesc "Show available GHCs and other tools")
|
)
|
||||||
)
|
|
||||||
)
|
)
|
||||||
<> command
|
<> command
|
||||||
"upgrade"
|
"upgrade"
|
||||||
@ -284,33 +287,95 @@ com =
|
|||||||
)
|
)
|
||||||
<> command
|
<> command
|
||||||
"changelog"
|
"changelog"
|
||||||
((info (fmap ChangeLog changelogP <**> helper)
|
((info
|
||||||
(progDesc "Find/show changelog"
|
(fmap ChangeLog changelogP <**> helper)
|
||||||
<> footerDoc (Just $ text changeLogFooter)
|
( progDesc "Find/show changelog"
|
||||||
)
|
<> footerDoc (Just $ text changeLogFooter)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
<> commandGroup "Other commands:"
|
<> commandGroup "Other commands:"
|
||||||
<> hidden
|
<> hidden
|
||||||
)
|
)
|
||||||
|
<|> subparser
|
||||||
|
( command
|
||||||
|
"install-cabal"
|
||||||
|
((info
|
||||||
|
((InstallCabalLegacy <$> installOpts) <**> helper)
|
||||||
|
( progDesc "Install or update cabal"
|
||||||
|
<> footerDoc (Just $ text installCabalFooter)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
<> internal
|
||||||
|
)
|
||||||
where
|
where
|
||||||
installFooter = [i|Discussion:
|
installToolFooter :: String
|
||||||
Installs the specified GHC version (or a recommended default one) into
|
installToolFooter = [i|Discussion:
|
||||||
a self-contained "~/.ghcup/ghc/<ghcver>" directory
|
Installs GHC or cabal. When no command is given, installs GHC
|
||||||
and symlinks the ghc binaries to "~/.ghcup/bin/<binary>-<ghcver>".|]
|
with the specified version/tag.
|
||||||
|
It is recommended to always specify a subcommand ('ghc' or 'cabal').|]
|
||||||
|
|
||||||
|
setFooter :: String
|
||||||
setFooter = [i|Discussion:
|
setFooter = [i|Discussion:
|
||||||
Sets the the current GHC version by creating non-versioned
|
Sets the currently active GHC or cabal version. When no command is given,
|
||||||
symlinks for all ghc binaries of the specified version in
|
defaults to setting GHC with the specified version/tag (if no tag
|
||||||
"~/.ghcup/bin/<binary>".|]
|
is given, sets GHC to 'recommended' version).
|
||||||
installCabalFooter = [i|Discussion:
|
It is recommended to always specify a subcommand ('ghc' or 'cabal').|]
|
||||||
|
|
||||||
|
rmFooter :: String
|
||||||
|
rmFooter = [i|Discussion:
|
||||||
|
Remove the given GHC or cabal version. When no command is given,
|
||||||
|
defaults to removing GHC with the specified version.
|
||||||
|
It is recommended to always specify a subcommand ('ghc' or 'cabal').|]
|
||||||
|
|
||||||
|
changeLogFooter :: String
|
||||||
|
changeLogFooter = [i|Discussion:
|
||||||
|
By default returns the URI of the ChangeLog of the latest GHC release.
|
||||||
|
Pass '-o' to automatically open via xdg-open.|]
|
||||||
|
|
||||||
|
|
||||||
|
installCabalFooter :: String
|
||||||
|
installCabalFooter = [i|Discussion:
|
||||||
Installs the specified cabal-install version (or a recommended default one)
|
Installs the specified cabal-install version (or a recommended default one)
|
||||||
into "~/.ghcup/bin", so it can be overwritten by later
|
into "~/.ghcup/bin", so it can be overwritten by later
|
||||||
"cabal install cabal-install", which installs into "~/.cabal/bin" by
|
"cabal install cabal-install", which installs into "~/.cabal/bin" by
|
||||||
default. Make sure to set up your PATH appropriately, so the cabal
|
default. Make sure to set up your PATH appropriately, so the cabal
|
||||||
installation takes precedence.|]
|
installation takes precedence.|]
|
||||||
changeLogFooter = [i|Discussion:
|
|
||||||
By default returns the URI of the ChangeLog of the latest GHC release.
|
|
||||||
Pass '-o' to automatically open via xdg-open.|]
|
installParser :: Parser (Either InstallCommand InstallOptions)
|
||||||
|
installParser =
|
||||||
|
(Left <$> subparser
|
||||||
|
( command
|
||||||
|
"ghc"
|
||||||
|
( InstallGHC
|
||||||
|
<$> (info
|
||||||
|
(installOpts <**> helper)
|
||||||
|
( progDesc "Install GHC"
|
||||||
|
<> footerDoc (Just $ text installGHCFooter)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
<> command
|
||||||
|
"cabal"
|
||||||
|
( InstallCabal
|
||||||
|
<$> (info
|
||||||
|
(installOpts <**> helper)
|
||||||
|
( progDesc "Install Cabal"
|
||||||
|
<> footerDoc (Just $ text installCabalFooter)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
<|> (Right <$> installOpts)
|
||||||
|
where
|
||||||
|
installGHCFooter :: String
|
||||||
|
installGHCFooter = [i|Discussion:
|
||||||
|
Installs the specified GHC version (or a recommended default one) into
|
||||||
|
a self-contained "~/.ghcup/ghc/<ghcver>" directory
|
||||||
|
and symlinks the ghc binaries to "~/.ghcup/bin/<binary>-<ghcver>".|]
|
||||||
|
|
||||||
|
|
||||||
installOpts :: Parser InstallOptions
|
installOpts :: Parser InstallOptions
|
||||||
@ -330,8 +395,46 @@ installOpts =
|
|||||||
<*> optional toolVersionArgument
|
<*> optional toolVersionArgument
|
||||||
|
|
||||||
|
|
||||||
setGHCOpts :: Parser SetGHCOptions
|
setParser :: Parser (Either SetCommand SetOptions)
|
||||||
setGHCOpts = SetGHCOptions <$> optional toolVersionArgument
|
setParser =
|
||||||
|
(Left <$> subparser
|
||||||
|
( command
|
||||||
|
"ghc"
|
||||||
|
( SetGHC
|
||||||
|
<$> (info
|
||||||
|
(setOpts <**> helper)
|
||||||
|
( progDesc "Set GHC version"
|
||||||
|
<> footerDoc (Just $ text setGHCFooter)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
<> command
|
||||||
|
"cabal"
|
||||||
|
( SetCabal
|
||||||
|
<$> (info
|
||||||
|
(setOpts <**> helper)
|
||||||
|
( progDesc "Set Cabal version"
|
||||||
|
<> footerDoc (Just $ text setCabalFooter)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
<|> (Right <$> setOpts)
|
||||||
|
where
|
||||||
|
setGHCFooter :: String
|
||||||
|
setGHCFooter = [i|Discussion:
|
||||||
|
Sets the the current GHC version by creating non-versioned
|
||||||
|
symlinks for all ghc binaries of the specified version in
|
||||||
|
"~/.ghcup/bin/<binary>".|]
|
||||||
|
|
||||||
|
setCabalFooter :: String
|
||||||
|
setCabalFooter = [i|Discussion:
|
||||||
|
Sets the the current Cabal version.|]
|
||||||
|
|
||||||
|
|
||||||
|
setOpts :: Parser SetOptions
|
||||||
|
setOpts = SetOptions <$> optional toolVersionArgument
|
||||||
|
|
||||||
listOpts :: Parser ListOptions
|
listOpts :: Parser ListOptions
|
||||||
listOpts =
|
listOpts =
|
||||||
@ -357,6 +460,26 @@ listOpts =
|
|||||||
(short 'r' <> long "raw-format" <> help "More machine-parsable format"
|
(short 'r' <> long "raw-format" <> help "More machine-parsable format"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
rmParser :: Parser (Either RmCommand RmOptions)
|
||||||
|
rmParser =
|
||||||
|
(Left <$> subparser
|
||||||
|
( command
|
||||||
|
"ghc"
|
||||||
|
(RmGHC <$> (info (rmOpts <**> helper) (progDesc "Remove GHC version")))
|
||||||
|
<> command
|
||||||
|
"cabal"
|
||||||
|
( RmCabal
|
||||||
|
<$> (info (versionParser' <**> helper)
|
||||||
|
(progDesc "Remove Cabal version")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
<|> (Right <$> rmOpts)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
rmOpts :: Parser RmOptions
|
rmOpts :: Parser RmOptions
|
||||||
rmOpts = RmOptions <$> versionArgument
|
rmOpts = RmOptions <$> versionArgument
|
||||||
|
|
||||||
@ -534,6 +657,12 @@ versionParser = option
|
|||||||
(short 'v' <> long "version" <> metavar "VERSION" <> help "The target version"
|
(short 'v' <> long "version" <> metavar "VERSION" <> help "The target version"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
versionParser' :: Parser Version
|
||||||
|
versionParser' = argument
|
||||||
|
(eitherReader (bimap show id . version . T.pack))
|
||||||
|
(metavar "VERSION")
|
||||||
|
|
||||||
|
|
||||||
tagEither :: String -> Either String Tag
|
tagEither :: String -> Either String Tag
|
||||||
tagEither s' = case fmap toLower s' of
|
tagEither s' = case fmap toLower s' of
|
||||||
"recommended" -> Right Recommended
|
"recommended" -> Right Recommended
|
||||||
@ -744,7 +873,11 @@ Report bugs at <https://gitlab.haskell.org/haskell/ghcup-hs/issues>|]
|
|||||||
, rawOutter = appendFile logfile
|
, rawOutter = appendFile logfile
|
||||||
}
|
}
|
||||||
|
|
||||||
-- wrapper to run effects with settings
|
|
||||||
|
-------------------------
|
||||||
|
-- Effect interpreters --
|
||||||
|
-------------------------
|
||||||
|
|
||||||
let runInstTool =
|
let runInstTool =
|
||||||
runLogger
|
runLogger
|
||||||
. flip runReaderT settings
|
. flip runReaderT settings
|
||||||
@ -776,6 +909,14 @@ Report bugs at <https://gitlab.haskell.org/haskell/ghcup-hs/issues>|]
|
|||||||
, TagNotFound
|
, TagNotFound
|
||||||
]
|
]
|
||||||
|
|
||||||
|
let
|
||||||
|
runSetCabal =
|
||||||
|
runLogger
|
||||||
|
. runE
|
||||||
|
@'[ NotInstalled
|
||||||
|
, TagNotFound
|
||||||
|
]
|
||||||
|
|
||||||
let runListGHC = runE @'[] . runLogger
|
let runListGHC = runE @'[] . runLogger
|
||||||
|
|
||||||
let runRmGHC =
|
let runRmGHC =
|
||||||
@ -811,13 +952,16 @@ Report bugs at <https://gitlab.haskell.org/haskell/ghcup-hs/issues>|]
|
|||||||
. flip runReaderT settings
|
. flip runReaderT settings
|
||||||
. runResourceT
|
. runResourceT
|
||||||
. runE
|
. runE
|
||||||
@'[ BuildFailed
|
@'[ AlreadyInstalled
|
||||||
|
, BuildFailed
|
||||||
|
, CopyError
|
||||||
, DigestError
|
, DigestError
|
||||||
, DistroNotFound
|
, DistroNotFound
|
||||||
, DownloadFailed
|
, DownloadFailed
|
||||||
, NoCompatibleArch
|
, NoCompatibleArch
|
||||||
, NoCompatiblePlatform
|
, NoCompatiblePlatform
|
||||||
, NoDownload
|
, NoDownload
|
||||||
|
, NotInstalled
|
||||||
, PatchFailed
|
, PatchFailed
|
||||||
, UnknownArchive
|
, UnknownArchive
|
||||||
]
|
]
|
||||||
@ -838,6 +982,11 @@ Report bugs at <https://gitlab.haskell.org/haskell/ghcup-hs/issues>|]
|
|||||||
, DownloadFailed
|
, DownloadFailed
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
---------------------------
|
||||||
|
-- Getting download info --
|
||||||
|
---------------------------
|
||||||
|
|
||||||
(GHCupInfo treq dls) <-
|
(GHCupInfo treq dls) <-
|
||||||
( runLogger
|
( runLogger
|
||||||
. flip runReaderT settings
|
. flip runReaderT settings
|
||||||
@ -853,79 +1002,134 @@ Report bugs at <https://gitlab.haskell.org/haskell/ghcup-hs/issues>|]
|
|||||||
exitWith (ExitFailure 2)
|
exitWith (ExitFailure 2)
|
||||||
runLogger $ checkForUpdates dls
|
runLogger $ checkForUpdates dls
|
||||||
|
|
||||||
|
|
||||||
|
-----------------------
|
||||||
|
-- Command functions --
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
let installGHC InstallOptions{..} =
|
||||||
|
(runInstTool $ do
|
||||||
|
v <- liftE $ fromVersion dls instVer GHC
|
||||||
|
liftE $ installGHCBin dls (_tvVersion v) instPlatform -- FIXME: ugly sharing of tool version
|
||||||
|
)
|
||||||
|
>>= \case
|
||||||
|
VRight _ -> do
|
||||||
|
runLogger $ $(logInfo) ("GHC installation successful")
|
||||||
|
pure ExitSuccess
|
||||||
|
VLeft (V (AlreadyInstalled _ v)) -> do
|
||||||
|
runLogger $ $(logWarn)
|
||||||
|
[i|GHC ver #{prettyVer v} already installed|]
|
||||||
|
pure ExitSuccess
|
||||||
|
VLeft (V (BuildFailed tmpdir e)) -> do
|
||||||
|
case keepDirs of
|
||||||
|
Never -> runLogger ($(logError) [i|Build failed with #{e}|])
|
||||||
|
_ -> runLogger ($(logError) [i|Build failed with #{e}
|
||||||
|
Check the logs at ~/.ghcup/logs and the build directory #{tmpdir} for more clues.
|
||||||
|
Make sure to clean up #{tmpdir} afterwards.|])
|
||||||
|
pure $ ExitFailure 3
|
||||||
|
VLeft (V NoDownload) -> do
|
||||||
|
|
||||||
|
runLogger $ do
|
||||||
|
case instVer of
|
||||||
|
Just iver -> $(logError) [i|No available GHC version for #{prettyToolVer iver}|]
|
||||||
|
Nothing -> $(logError) [i|No available recommended GHC version|]
|
||||||
|
pure $ ExitFailure 3
|
||||||
|
VLeft e -> do
|
||||||
|
runLogger $ do
|
||||||
|
$(logError) [i|#{e}|]
|
||||||
|
$(logError) [i|Also check the logs in ~/.ghcup/logs|]
|
||||||
|
pure $ ExitFailure 3
|
||||||
|
|
||||||
|
|
||||||
|
let installCabal InstallOptions{..} =
|
||||||
|
(runInstTool $ do
|
||||||
|
v <- liftE $ fromVersion dls instVer Cabal
|
||||||
|
liftE $ installCabalBin dls (_tvVersion v) instPlatform -- FIXME: ugly sharing of tool version
|
||||||
|
)
|
||||||
|
>>= \case
|
||||||
|
VRight _ -> do
|
||||||
|
runLogger $ $(logInfo) ("Cabal installation successful")
|
||||||
|
pure ExitSuccess
|
||||||
|
VLeft (V (AlreadyInstalled _ v)) -> do
|
||||||
|
runLogger $ $(logWarn)
|
||||||
|
[i|Cabal ver #{prettyVer v} already installed|]
|
||||||
|
pure ExitSuccess
|
||||||
|
VLeft (V NoDownload) -> do
|
||||||
|
|
||||||
|
runLogger $ do
|
||||||
|
case instVer of
|
||||||
|
Just iver -> $(logError) [i|No available Cabal version for #{prettyToolVer iver}|]
|
||||||
|
Nothing -> $(logError) [i|No available recommended Cabal version|]
|
||||||
|
pure $ ExitFailure 4
|
||||||
|
VLeft e -> do
|
||||||
|
runLogger $ do
|
||||||
|
$(logError) [i|#{e}|]
|
||||||
|
$(logError) [i|Also check the logs in ~/.ghcup/logs|]
|
||||||
|
pure $ ExitFailure 4
|
||||||
|
|
||||||
|
let setGHC' SetOptions{..} =
|
||||||
|
(runSetGHC $ do
|
||||||
|
v <- liftE $ fromVersion dls sToolVer GHC
|
||||||
|
liftE $ setGHC v SetGHCOnly
|
||||||
|
)
|
||||||
|
>>= \case
|
||||||
|
VRight (GHCTargetVersion{..}) -> do
|
||||||
|
runLogger
|
||||||
|
$ $(logInfo)
|
||||||
|
[i|GHC #{prettyVer _tvVersion} successfully set as default version#{maybe "" (" for cross target " <>) _tvTarget}|]
|
||||||
|
pure ExitSuccess
|
||||||
|
VLeft e -> do
|
||||||
|
runLogger ($(logError) [i|#{e}|])
|
||||||
|
pure $ ExitFailure 5
|
||||||
|
|
||||||
|
let setCabal' SetOptions{..} =
|
||||||
|
(runSetCabal $ do
|
||||||
|
v <- liftE $ fromVersion dls sToolVer Cabal
|
||||||
|
liftE $ setCabal (_tvVersion v)
|
||||||
|
)
|
||||||
|
>>= \case
|
||||||
|
VRight _ -> pure ExitSuccess
|
||||||
|
VLeft e -> do
|
||||||
|
runLogger ($(logError) [i|#{e}|])
|
||||||
|
pure $ ExitFailure 14
|
||||||
|
|
||||||
|
let rmGHC' RmOptions{..} =
|
||||||
|
(runRmGHC $ do
|
||||||
|
liftE $ rmGHCVer ghcVer
|
||||||
|
)
|
||||||
|
>>= \case
|
||||||
|
VRight _ -> pure ExitSuccess
|
||||||
|
VLeft e -> do
|
||||||
|
runLogger ($(logError) [i|#{e}|])
|
||||||
|
pure $ ExitFailure 7
|
||||||
|
|
||||||
|
let rmCabal' tv =
|
||||||
|
(runSetCabal $ do
|
||||||
|
liftE $ rmCabalVer tv
|
||||||
|
)
|
||||||
|
>>= \case
|
||||||
|
VRight _ -> pure ExitSuccess
|
||||||
|
VLeft e -> do
|
||||||
|
runLogger ($(logError) [i|#{e}|])
|
||||||
|
pure $ ExitFailure 15
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
res <- case optCommand of
|
res <- case optCommand of
|
||||||
Install (InstallOptions {..}) ->
|
Install (Right iopts) -> do
|
||||||
(runInstTool $ do
|
runLogger ($(logWarn) [i|This is an old-style command for installing GHC. Use 'ghcup install ghc' instead.|])
|
||||||
v <- liftE $ fromVersion dls instVer GHC
|
installGHC iopts
|
||||||
liftE $ installGHCBin dls (_tvVersion v) instPlatform -- FIXME: ugly sharing of tool version
|
Install (Left (InstallGHC iopts)) -> installGHC iopts
|
||||||
)
|
Install (Left (InstallCabal iopts)) -> installCabal iopts
|
||||||
>>= \case
|
InstallCabalLegacy iopts -> do
|
||||||
VRight _ -> do
|
runLogger ($(logWarn) [i|This is an old-style command for installing cabal. Use 'ghcup install cabal' instead.|])
|
||||||
runLogger $ $(logInfo) ("GHC installation successful")
|
installCabal iopts
|
||||||
pure ExitSuccess
|
|
||||||
VLeft (V (AlreadyInstalled _ v)) -> do
|
|
||||||
runLogger $ $(logWarn)
|
|
||||||
[i|GHC ver #{prettyVer v} already installed|]
|
|
||||||
pure ExitSuccess
|
|
||||||
VLeft (V (BuildFailed tmpdir e)) -> do
|
|
||||||
case keepDirs of
|
|
||||||
Never -> runLogger ($(logError) [i|Build failed with #{e}|])
|
|
||||||
_ -> runLogger ($(logError) [i|Build failed with #{e}
|
|
||||||
Check the logs at ~/.ghcup/logs and the build directory #{tmpdir} for more clues.
|
|
||||||
Make sure to clean up #{tmpdir} afterwards.|])
|
|
||||||
pure $ ExitFailure 3
|
|
||||||
VLeft (V NoDownload) -> do
|
|
||||||
|
|
||||||
runLogger $ do
|
Set (Right sopts) -> do
|
||||||
case instVer of
|
runLogger ($(logWarn) [i|This is an old-style command for setting GHC. Use 'ghcup set ghc' instead.|])
|
||||||
Just iver -> $(logError) [i|No available GHC version for #{prettyToolVer iver}|]
|
setGHC' sopts
|
||||||
Nothing -> $(logError) [i|No available recommended GHC version|]
|
Set (Left (SetGHC sopts)) -> setGHC' sopts
|
||||||
pure $ ExitFailure 3
|
Set (Left (SetCabal sopts)) -> setCabal' sopts
|
||||||
VLeft e -> do
|
|
||||||
runLogger $ do
|
|
||||||
$(logError) [i|#{e}|]
|
|
||||||
$(logError) [i|Also check the logs in ~/.ghcup/logs|]
|
|
||||||
pure $ ExitFailure 3
|
|
||||||
InstallCabal (InstallOptions {..}) ->
|
|
||||||
(runInstTool $ do
|
|
||||||
v <- liftE $ fromVersion dls instVer Cabal
|
|
||||||
liftE $ installCabalBin dls (_tvVersion v) instPlatform -- FIXME: ugly sharing of tool version
|
|
||||||
)
|
|
||||||
>>= \case
|
|
||||||
VRight _ -> do
|
|
||||||
runLogger $ $(logInfo) ("Cabal installation successful")
|
|
||||||
pure ExitSuccess
|
|
||||||
VLeft (V (AlreadyInstalled _ v)) -> do
|
|
||||||
runLogger $ $(logWarn)
|
|
||||||
[i|Cabal ver #{prettyVer v} already installed|]
|
|
||||||
pure ExitSuccess
|
|
||||||
VLeft (V NoDownload) -> do
|
|
||||||
|
|
||||||
runLogger $ do
|
|
||||||
case instVer of
|
|
||||||
Just iver -> $(logError) [i|No available Cabal version for #{prettyToolVer iver}|]
|
|
||||||
Nothing -> $(logError) [i|No available recommended Cabal version|]
|
|
||||||
pure $ ExitFailure 4
|
|
||||||
VLeft e -> do
|
|
||||||
runLogger $ do
|
|
||||||
$(logError) [i|#{e}|]
|
|
||||||
$(logError) [i|Also check the logs in ~/.ghcup/logs|]
|
|
||||||
pure $ ExitFailure 4
|
|
||||||
|
|
||||||
SetGHC (SetGHCOptions {..}) ->
|
|
||||||
(runSetGHC $ do
|
|
||||||
v <- liftE $ fromVersion dls ghcVer GHC
|
|
||||||
liftE $ setGHC v SetGHCOnly
|
|
||||||
)
|
|
||||||
>>= \case
|
|
||||||
VRight (GHCTargetVersion{..}) -> do
|
|
||||||
runLogger
|
|
||||||
$ $(logInfo)
|
|
||||||
[i|GHC #{prettyVer _tvVersion} successfully set as default version#{maybe "" (" for cross target " <>) _tvTarget}|]
|
|
||||||
pure ExitSuccess
|
|
||||||
VLeft e -> do
|
|
||||||
runLogger ($(logError) [i|#{e}|])
|
|
||||||
pure $ ExitFailure 5
|
|
||||||
|
|
||||||
List (ListOptions {..}) ->
|
List (ListOptions {..}) ->
|
||||||
(runListGHC $ do
|
(runListGHC $ do
|
||||||
@ -940,15 +1144,11 @@ Make sure to clean up #{tmpdir} afterwards.|])
|
|||||||
runLogger ($(logError) [i|#{e}|])
|
runLogger ($(logError) [i|#{e}|])
|
||||||
pure $ ExitFailure 6
|
pure $ ExitFailure 6
|
||||||
|
|
||||||
Rm (RmOptions {..}) ->
|
Rm (Right rmopts) -> do
|
||||||
(runRmGHC $ do
|
runLogger ($(logWarn) [i|This is an old-style command for removing GHC. Use 'ghcup rm ghc' instead.|])
|
||||||
liftE $ rmGHCVer ghcVer
|
rmGHC' rmopts
|
||||||
)
|
Rm (Left (RmGHC rmopts)) -> rmGHC' rmopts
|
||||||
>>= \case
|
Rm (Left (RmCabal rmopts)) -> rmCabal' rmopts
|
||||||
VRight _ -> pure ExitSuccess
|
|
||||||
VLeft e -> do
|
|
||||||
runLogger ($(logError) [i|#{e}|])
|
|
||||||
pure $ ExitFailure 7
|
|
||||||
|
|
||||||
DInfo ->
|
DInfo ->
|
||||||
do
|
do
|
||||||
@ -1182,14 +1382,14 @@ checkForUpdates dls = do
|
|||||||
forM mghc_ver $ \ghc_ver ->
|
forM mghc_ver $ \ghc_ver ->
|
||||||
when (l > ghc_ver)
|
when (l > ghc_ver)
|
||||||
$ $(logWarn)
|
$ $(logWarn)
|
||||||
[i|New GHC version available: #{prettyVer l}. To upgrade, run 'ghcup install #{prettyVer l}'|]
|
[i|New GHC version available: #{prettyVer l}. To upgrade, run 'ghcup install ghc #{prettyVer l}'|]
|
||||||
|
|
||||||
forM_ (getLatest dls Cabal) $ \l -> do
|
forM_ (getLatest dls Cabal) $ \l -> do
|
||||||
mcabal_ver <- latestInstalled Cabal
|
mcabal_ver <- latestInstalled Cabal
|
||||||
forM mcabal_ver $ \cabal_ver ->
|
forM mcabal_ver $ \cabal_ver ->
|
||||||
when (l > cabal_ver)
|
when (l > cabal_ver)
|
||||||
$ $(logWarn)
|
$ $(logWarn)
|
||||||
[i|New Cabal version available: #{prettyVer l}. To upgrade, run 'ghcup install-cabal #{prettyVer l}'|]
|
[i|New Cabal version available: #{prettyVer l}. To upgrade, run 'ghcup install cabal #{prettyVer l}'|]
|
||||||
|
|
||||||
where
|
where
|
||||||
latestInstalled tool = (fmap lVer . lastMay)
|
latestInstalled tool = (fmap lVer . lastMay)
|
||||||
|
155
lib/GHCup.hs
155
lib/GHCup.hs
@ -38,6 +38,7 @@ import Control.Monad.Reader
|
|||||||
import Control.Monad.Trans.Resource
|
import Control.Monad.Trans.Resource
|
||||||
hiding ( throwM )
|
hiding ( throwM )
|
||||||
import Data.ByteString ( ByteString )
|
import Data.ByteString ( ByteString )
|
||||||
|
import Data.Either
|
||||||
import Data.List
|
import Data.List
|
||||||
import Data.Maybe
|
import Data.Maybe
|
||||||
import Data.String.Interpolate
|
import Data.String.Interpolate
|
||||||
@ -53,6 +54,7 @@ import Prelude hiding ( abs
|
|||||||
, readFile
|
, readFile
|
||||||
, writeFile
|
, writeFile
|
||||||
)
|
)
|
||||||
|
import Safe hiding ( at )
|
||||||
import System.IO.Error
|
import System.IO.Error
|
||||||
import System.Posix.Env.ByteString ( getEnvironment )
|
import System.Posix.Env.ByteString ( getEnvironment )
|
||||||
import System.Posix.FilePath ( getSearchPath )
|
import System.Posix.FilePath ( getSearchPath )
|
||||||
@ -148,24 +150,39 @@ installCabalBin :: ( MonadMask m
|
|||||||
, MonadLogger m
|
, MonadLogger m
|
||||||
, MonadResource m
|
, MonadResource m
|
||||||
, MonadIO m
|
, MonadIO m
|
||||||
|
, MonadFail m
|
||||||
)
|
)
|
||||||
=> GHCupDownloads
|
=> GHCupDownloads
|
||||||
-> Version
|
-> Version
|
||||||
-> Maybe PlatformRequest -- ^ if Nothing, looks up current host platform
|
-> Maybe PlatformRequest -- ^ if Nothing, looks up current host platform
|
||||||
-> Excepts
|
-> Excepts
|
||||||
'[ CopyError
|
'[ AlreadyInstalled
|
||||||
|
, CopyError
|
||||||
, DigestError
|
, DigestError
|
||||||
, DistroNotFound
|
, DistroNotFound
|
||||||
, DownloadFailed
|
, DownloadFailed
|
||||||
, NoCompatibleArch
|
, NoCompatibleArch
|
||||||
, NoCompatiblePlatform
|
, NoCompatiblePlatform
|
||||||
, NoDownload
|
, NoDownload
|
||||||
|
, NotInstalled
|
||||||
, UnknownArchive
|
, UnknownArchive
|
||||||
]
|
]
|
||||||
m
|
m
|
||||||
()
|
()
|
||||||
installCabalBin bDls ver mpfReq = do
|
installCabalBin bDls ver mpfReq = do
|
||||||
lift $ $(logDebug) [i|Requested to install cabal version #{ver}|]
|
lift $ $(logDebug) [i|Requested to install cabal version #{ver}|]
|
||||||
|
|
||||||
|
bindir <- liftIO ghcupBinDir
|
||||||
|
|
||||||
|
whenM
|
||||||
|
(liftIO $ cabalInstalled ver >>= \a ->
|
||||||
|
handleIO (\_ -> pure False)
|
||||||
|
$ fmap (\x -> a && isSymbolicLink x)
|
||||||
|
-- ignore when the installation is a legacy cabal (binary, not symlink)
|
||||||
|
$ getSymbolicLinkStatus (toFilePath (bindir </> [rel|cabal|]))
|
||||||
|
)
|
||||||
|
$ (throwE $ AlreadyInstalled Cabal ver)
|
||||||
|
|
||||||
Settings {..} <- lift ask
|
Settings {..} <- lift ask
|
||||||
pfreq@(PlatformRequest {..}) <- maybe (liftE $ platformRequest) pure mpfReq
|
pfreq@(PlatformRequest {..}) <- maybe (liftE $ platformRequest) pure mpfReq
|
||||||
|
|
||||||
@ -178,13 +195,16 @@ installCabalBin bDls ver mpfReq = do
|
|||||||
liftE $ unpackToDir tmpUnpack dl
|
liftE $ unpackToDir tmpUnpack dl
|
||||||
void $ liftIO $ darwinNotarization _rPlatform tmpUnpack
|
void $ liftIO $ darwinNotarization _rPlatform tmpUnpack
|
||||||
|
|
||||||
-- prepare paths
|
|
||||||
bindir <- liftIO ghcupBinDir
|
|
||||||
|
|
||||||
-- the subdir of the archive where we do the work
|
-- the subdir of the archive where we do the work
|
||||||
let workdir = maybe tmpUnpack (tmpUnpack </>) (view dlSubdir dlinfo)
|
let workdir = maybe tmpUnpack (tmpUnpack </>) (view dlSubdir dlinfo)
|
||||||
|
|
||||||
liftE $ installCabal' workdir bindir
|
liftE $ installCabal' workdir bindir
|
||||||
|
|
||||||
|
-- create symlink if this is the latest version
|
||||||
|
cVers <- liftIO $ fmap rights $ getInstalledCabals
|
||||||
|
let lInstCabal = headMay . reverse . sort $ cVers
|
||||||
|
when (maybe True (ver >=) lInstCabal) $ liftE $ setCabal ver
|
||||||
|
|
||||||
pure ()
|
pure ()
|
||||||
|
|
||||||
where
|
where
|
||||||
@ -197,16 +217,17 @@ installCabalBin bDls ver mpfReq = do
|
|||||||
lift $ $(logInfo) "Installing cabal"
|
lift $ $(logInfo) "Installing cabal"
|
||||||
let cabalFile = [rel|cabal|]
|
let cabalFile = [rel|cabal|]
|
||||||
liftIO $ createDirIfMissing newDirPerms inst
|
liftIO $ createDirIfMissing newDirPerms inst
|
||||||
|
destFileName <- lift $ parseRel (toFilePath cabalFile <> "-" <> verToBS ver)
|
||||||
handleIO (throwE . CopyError . show) $ liftIO $ copyFile
|
handleIO (throwE . CopyError . show) $ liftIO $ copyFile
|
||||||
(path </> cabalFile)
|
(path </> cabalFile)
|
||||||
(inst </> cabalFile)
|
(inst </> destFileName)
|
||||||
Overwrite
|
Overwrite
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
---------------
|
---------------------
|
||||||
--[ Set GHC ]--
|
--[ Set GHC/cabal ]--
|
||||||
---------------
|
---------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -283,6 +304,40 @@ setGHC ver sghc = do
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- | Set the ~/.ghcup/bin/cabal symlink.
|
||||||
|
setCabal :: (MonadLogger m, MonadThrow m, MonadFail m, MonadIO m)
|
||||||
|
=> Version
|
||||||
|
-> Excepts '[NotInstalled] m ()
|
||||||
|
setCabal ver = do
|
||||||
|
let verBS = verToBS ver
|
||||||
|
targetFile <- parseRel ("cabal-" <> verBS)
|
||||||
|
|
||||||
|
-- symlink destination
|
||||||
|
bindir <- liftIO $ ghcupBinDir
|
||||||
|
liftIO $ hideError AlreadyExists $ createDirRecursive newDirPerms bindir
|
||||||
|
|
||||||
|
whenM (liftIO $ fmap not $ doesFileExist (bindir </> targetFile))
|
||||||
|
$ throwE
|
||||||
|
$ NotInstalled Cabal (prettyVer ver)
|
||||||
|
|
||||||
|
let cabalbin = bindir </> [rel|cabal|]
|
||||||
|
|
||||||
|
-- delete old file (may be binary or symlink)
|
||||||
|
lift $ $(logDebug) [i|rm -f #{toFilePath cabalbin}|]
|
||||||
|
liftIO $ hideError doesNotExistErrorType $ deleteFile
|
||||||
|
cabalbin
|
||||||
|
|
||||||
|
-- create symlink
|
||||||
|
let destL = toFilePath targetFile
|
||||||
|
lift $ $(logDebug) [i|ln -s #{destL} #{toFilePath cabalbin}|]
|
||||||
|
liftIO $ createSymlink cabalbin destL
|
||||||
|
|
||||||
|
pure ()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
------------------
|
------------------
|
||||||
--[ List tools ]--
|
--[ List tools ]--
|
||||||
@ -386,8 +441,8 @@ listVersions av lt criteria = case lt of
|
|||||||
fromSrc <- ghcSrcInstalled tver
|
fromSrc <- ghcSrcInstalled tver
|
||||||
pure ListResult { lVer = v, lCross = Nothing , lTag = tags, lTool = t, lStray = False, .. }
|
pure ListResult { lVer = v, lCross = Nothing , lTag = tags, lTool = t, lStray = False, .. }
|
||||||
Cabal -> do
|
Cabal -> do
|
||||||
lSet <- fmap (== v) $ cabalSet
|
lSet <- fmap (maybe False (== v)) $ cabalSet
|
||||||
let lInstalled = lSet
|
lInstalled <- cabalInstalled v
|
||||||
pure ListResult { lVer = v
|
pure ListResult { lVer = v
|
||||||
, lCross = Nothing
|
, lCross = Nothing
|
||||||
, lTag = tags
|
, lTag = tags
|
||||||
@ -417,9 +472,9 @@ listVersions av lt criteria = case lt of
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
--------------
|
--------------------
|
||||||
--[ GHC rm ]--
|
--[ GHC/cabal rm ]--
|
||||||
--------------
|
--------------------
|
||||||
|
|
||||||
|
|
||||||
-- | This function may throw and crash in various ways.
|
-- | This function may throw and crash in various ways.
|
||||||
@ -461,6 +516,26 @@ rmGHCVer ver = do
|
|||||||
else throwE (NotInstalled GHC (ver ^. tvVersion % to prettyVer))
|
else throwE (NotInstalled GHC (ver ^. tvVersion % to prettyVer))
|
||||||
|
|
||||||
|
|
||||||
|
-- | This function may throw and crash in various ways.
|
||||||
|
rmCabalVer :: (MonadThrow m, MonadLogger m, MonadIO m, MonadFail m)
|
||||||
|
=> Version
|
||||||
|
-> Excepts '[NotInstalled] m ()
|
||||||
|
rmCabalVer ver = do
|
||||||
|
whenM (fmap not $ liftIO $ cabalInstalled ver) $ throwE (NotInstalled GHC (prettyVer ver))
|
||||||
|
|
||||||
|
cSet <- liftIO cabalSet
|
||||||
|
|
||||||
|
bindir <- liftIO ghcupBinDir
|
||||||
|
cabalFile <- lift $ parseRel ("cabal-" <> verToBS ver)
|
||||||
|
liftIO $ hideError doesNotExistErrorType $ deleteFile (bindir </> cabalFile)
|
||||||
|
|
||||||
|
when (maybe False (== ver) cSet) $ do
|
||||||
|
cVers <- liftIO $ fmap rights $ getInstalledCabals
|
||||||
|
case headMay . reverse . sort $ cVers of
|
||||||
|
Just latestver -> setCabal latestver
|
||||||
|
Nothing -> liftIO $ hideError doesNotExistErrorType $ deleteFile
|
||||||
|
(bindir </> [rel|cabal|])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
------------------
|
------------------
|
||||||
@ -671,26 +746,29 @@ Stage1Only = YES|]
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
compileCabal :: ( MonadReader Settings m
|
compileCabal :: ( MonadReader Settings m
|
||||||
, MonadResource m
|
, MonadResource m
|
||||||
, MonadMask m
|
, MonadMask m
|
||||||
, MonadLogger m
|
, MonadLogger m
|
||||||
, MonadIO m
|
, MonadIO m
|
||||||
|
, MonadFail m
|
||||||
)
|
)
|
||||||
=> GHCupDownloads
|
=> GHCupDownloads
|
||||||
-> Version -- ^ version to install
|
-> Version -- ^ version to install
|
||||||
-> Either Version (Path Abs) -- ^ version to bootstrap with
|
-> Either Version (Path Abs) -- ^ version to bootstrap with
|
||||||
-> Maybe Int
|
-> Maybe Int
|
||||||
-> Maybe (Path Abs)
|
-> Maybe (Path Abs)
|
||||||
-> Excepts
|
-> Excepts
|
||||||
'[ BuildFailed
|
'[ AlreadyInstalled
|
||||||
|
, BuildFailed
|
||||||
|
, CopyError
|
||||||
, DigestError
|
, DigestError
|
||||||
, DistroNotFound
|
, DistroNotFound
|
||||||
, DownloadFailed
|
, DownloadFailed
|
||||||
, NoCompatibleArch
|
, NoCompatibleArch
|
||||||
, NoCompatiblePlatform
|
, NoCompatiblePlatform
|
||||||
, NoDownload
|
, NoDownload
|
||||||
|
, NotInstalled
|
||||||
, PatchFailed
|
, PatchFailed
|
||||||
, UnknownArchive
|
, UnknownArchive
|
||||||
]
|
]
|
||||||
@ -699,6 +777,17 @@ compileCabal :: ( MonadReader Settings m
|
|||||||
compileCabal dls tver bghc jobs patchdir = do
|
compileCabal dls tver bghc jobs patchdir = do
|
||||||
lift $ $(logDebug) [i|Requested to compile: #{tver} with ghc-#{bghc}|]
|
lift $ $(logDebug) [i|Requested to compile: #{tver} with ghc-#{bghc}|]
|
||||||
|
|
||||||
|
bindir <- liftIO ghcupBinDir
|
||||||
|
|
||||||
|
whenM
|
||||||
|
(liftIO $ cabalInstalled tver >>= \a ->
|
||||||
|
handleIO (\_ -> pure False)
|
||||||
|
$ fmap (\x -> a && isSymbolicLink x)
|
||||||
|
-- ignore when the installation is a legacy cabal (binary, not symlink)
|
||||||
|
$ getSymbolicLinkStatus (toFilePath (bindir </> [rel|cabal|]))
|
||||||
|
)
|
||||||
|
$ (throwE $ AlreadyInstalled Cabal tver)
|
||||||
|
|
||||||
-- download source tarball
|
-- download source tarball
|
||||||
dlInfo <- preview (ix Cabal % ix tver % viSourceDL % _Just) dls ?? NoDownload
|
dlInfo <- preview (ix Cabal % ix tver % viSourceDL % _Just) dls ?? NoDownload
|
||||||
dl <- liftE $ downloadCached dlInfo Nothing
|
dl <- liftE $ downloadCached dlInfo Nothing
|
||||||
@ -711,21 +800,25 @@ compileCabal dls tver bghc jobs patchdir = do
|
|||||||
|
|
||||||
let workdir = maybe id (flip (</>)) (view dlSubdir dlInfo) $ tmpUnpack
|
let workdir = maybe id (flip (</>)) (view dlSubdir dlInfo) $ tmpUnpack
|
||||||
|
|
||||||
|
cbin <- liftE $ runBuildAction tmpUnpack Nothing (compile workdir)
|
||||||
|
|
||||||
liftE $ runBuildAction
|
destFileName <- lift $ parseRel ("cabal-" <> verToBS tver)
|
||||||
tmpUnpack
|
handleIO (throwE . CopyError . show) $ liftIO $ copyFile
|
||||||
Nothing
|
cbin
|
||||||
(compile workdir)
|
(bindir </> destFileName)
|
||||||
|
Overwrite
|
||||||
|
|
||||||
-- only clean up dir if the build succeeded
|
-- create symlink if this is the latest version
|
||||||
liftIO $ deleteDirRecursive tmpUnpack
|
cVers <- liftIO $ fmap rights $ getInstalledCabals
|
||||||
|
let lInstCabal = headMay . reverse . sort $ cVers
|
||||||
|
when (maybe True (tver >=) lInstCabal) $ liftE $ setCabal tver
|
||||||
|
|
||||||
pure ()
|
pure ()
|
||||||
|
|
||||||
where
|
where
|
||||||
compile :: (MonadThrow m, MonadLogger m, MonadIO m)
|
compile :: (MonadThrow m, MonadLogger m, MonadIO m, MonadResource m)
|
||||||
=> Path Abs
|
=> Path Abs
|
||||||
-> Excepts '[ProcessError , PatchFailed] m ()
|
-> Excepts '[ProcessError , PatchFailed] m (Path Abs)
|
||||||
compile workdir = do
|
compile workdir = do
|
||||||
lift $ $(logInfo) [i|Building (this may take a while)...|]
|
lift $ $(logInfo) [i|Building (this may take a while)...|]
|
||||||
|
|
||||||
@ -741,14 +834,19 @@ compileCabal dls tver bghc jobs patchdir = do
|
|||||||
pure
|
pure
|
||||||
[ ("GHC" , toFilePath path)
|
[ ("GHC" , toFilePath path)
|
||||||
, ("GHC_PKG", dn <> "/" <> "ghc-pkg" <> ver)
|
, ("GHC_PKG", dn <> "/" <> "ghc-pkg" <> ver)
|
||||||
|
, ("HADDOCK", dn <> "/" <> "haddock" <> ver)
|
||||||
]
|
]
|
||||||
Left bver -> do
|
Left bver -> do
|
||||||
let v' = verToBS bver
|
let v' = verToBS bver
|
||||||
pure [("GHC", "ghc-" <> v'), ("GHC_PKG", "ghc-pkg-" <> v')]
|
pure
|
||||||
|
[ ("GHC" , "ghc-" <> v')
|
||||||
|
, ("GHC_PKG", "ghc-pkg-" <> v')
|
||||||
|
, ("HADDOCK", "haddock-" <> v')
|
||||||
|
]
|
||||||
|
|
||||||
cabal_bin <- liftIO $ ghcupBinDir
|
tmp <- lift withGHCupTmpDir
|
||||||
newEnv <- lift
|
liftIO $ createDirRecursive newDirPerms (tmp </> [rel|bin|])
|
||||||
$ addToCurrentEnv (("PREFIX", toFilePath cabal_bin) : ghcEnv)
|
newEnv <- lift $ addToCurrentEnv (("PREFIX", toFilePath tmp) : ghcEnv)
|
||||||
lift $ $(logDebug) [i|Environment: #{newEnv}|]
|
lift $ $(logDebug) [i|Environment: #{newEnv}|]
|
||||||
|
|
||||||
lEM $ liftIO $ execLogged "./bootstrap.sh"
|
lEM $ liftIO $ execLogged "./bootstrap.sh"
|
||||||
@ -757,6 +855,7 @@ compileCabal dls tver bghc jobs patchdir = do
|
|||||||
[rel|cabal-bootstrap|]
|
[rel|cabal-bootstrap|]
|
||||||
(Just workdir)
|
(Just workdir)
|
||||||
(Just newEnv)
|
(Just newEnv)
|
||||||
|
pure $ (tmp </> [rel|bin/cabal|])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -210,19 +210,41 @@ getInstalledGHCs = do
|
|||||||
Left _ -> pure $ Left f
|
Left _ -> pure $ Left f
|
||||||
|
|
||||||
|
|
||||||
|
getInstalledCabals :: IO [Either (Path Rel) Version]
|
||||||
|
getInstalledCabals = do
|
||||||
|
bindir <- liftIO $ ghcupBinDir
|
||||||
|
bins <- liftIO $ handleIO (\_ -> pure []) $ findFiles
|
||||||
|
bindir
|
||||||
|
(makeRegexOpts compExtended execBlank ([s|^cabal-.*$|] :: ByteString))
|
||||||
|
vs <- forM bins $ \f -> case fmap version (fmap decUTF8Safe . B.stripPrefix "cabal-" . toFilePath $ f) of
|
||||||
|
Just (Right r) -> pure $ Right r
|
||||||
|
Just (Left _) -> pure $ Left f
|
||||||
|
Nothing -> pure $ Left f
|
||||||
|
cs <- cabalSet -- for legacy cabal
|
||||||
|
pure $ maybe vs (\x -> Right x:vs) cs
|
||||||
|
|
||||||
|
|
||||||
cabalInstalled :: Version -> IO Bool
|
cabalInstalled :: Version -> IO Bool
|
||||||
cabalInstalled ver = do
|
cabalInstalled ver = do
|
||||||
reportedVer <- cabalSet
|
vers <- fmap rights $ getInstalledCabals
|
||||||
pure (reportedVer == ver)
|
pure $ elem ver $ vers
|
||||||
|
|
||||||
cabalSet :: (MonadIO m, MonadThrow m) => m Version
|
|
||||||
|
cabalSet :: (MonadIO m, MonadThrow m) => m (Maybe Version)
|
||||||
cabalSet = do
|
cabalSet = do
|
||||||
cabalbin <- (</> [rel|cabal|]) <$> liftIO ghcupBinDir
|
cabalbin <- (</> [rel|cabal|]) <$> liftIO ghcupBinDir
|
||||||
mc <- liftIO $ executeOut cabalbin ["--numeric-version"] Nothing
|
mc <- liftIO $ handleIO (\_ -> pure Nothing) $ fmap Just $ executeOut
|
||||||
let reportedVer = fst . B.spanEnd (== _lf) . _stdOut $ mc
|
cabalbin
|
||||||
case version $ decUTF8Safe reportedVer of
|
["--numeric-version"]
|
||||||
Left e -> throwM e
|
Nothing
|
||||||
Right r -> pure r
|
fmap join $ forM mc $ \c -> if
|
||||||
|
| not (B.null (_stdOut c))
|
||||||
|
, _exitCode c == ExitSuccess -> do
|
||||||
|
let reportedVer = fst . B.spanEnd (== _lf) . _stdOut $ c
|
||||||
|
case version $ decUTF8Safe reportedVer of
|
||||||
|
Left e -> throwM e
|
||||||
|
Right r -> pure $ Just r
|
||||||
|
| otherwise -> pure Nothing
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -463,11 +485,11 @@ getChangeLog dls tool (Right tag) =
|
|||||||
runBuildAction :: (Show (V e), MonadReader Settings m, MonadIO m, MonadMask m)
|
runBuildAction :: (Show (V e), MonadReader Settings m, MonadIO m, MonadMask m)
|
||||||
=> Path Abs -- ^ build directory
|
=> Path Abs -- ^ build directory
|
||||||
-> Maybe (Path Abs) -- ^ install location (e.g. for GHC)
|
-> Maybe (Path Abs) -- ^ install location (e.g. for GHC)
|
||||||
-> Excepts e m ()
|
-> Excepts e m a
|
||||||
-> Excepts '[BuildFailed] m ()
|
-> Excepts '[BuildFailed] m a
|
||||||
runBuildAction bdir instdir action = do
|
runBuildAction bdir instdir action = do
|
||||||
Settings {..} <- lift ask
|
Settings {..} <- lift ask
|
||||||
flip
|
v <- flip
|
||||||
onException
|
onException
|
||||||
(do
|
(do
|
||||||
forM_ instdir $ \dir ->
|
forM_ instdir $ \dir ->
|
||||||
@ -491,3 +513,4 @@ runBuildAction bdir instdir action = do
|
|||||||
|
|
||||||
when (keepDirs == Never || keepDirs == Errors) $ liftIO $ deleteDirRecursive
|
when (keepDirs == Never || keepDirs == Errors) $ liftIO $ deleteDirRecursive
|
||||||
bdir
|
bdir
|
||||||
|
pure v
|
||||||
|
Loading…
Reference in New Issue
Block a user