Merge remote-tracking branch 'origin/merge-requests/70'
This commit is contained in:
commit
45ab69960f
@ -192,10 +192,10 @@ data ChangeLogOptions = ChangeLogOptions
|
|||||||
-- by default. For example:
|
-- by default. For example:
|
||||||
--
|
--
|
||||||
-- > invertableSwitch "recursive" True (help "do not recurse into directories")
|
-- > invertableSwitch "recursive" True (help "do not recurse into directories")
|
||||||
--
|
--
|
||||||
-- This example makes --recursive enabled by default, so
|
-- This example makes --recursive enabled by default, so
|
||||||
-- 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
|
-> Char -- ^ short option for the non-default option
|
||||||
-> Bool -- ^ is switch enabled by default?
|
-> Bool -- ^ is switch enabled by default?
|
||||||
@ -363,7 +363,7 @@ com =
|
|||||||
( command
|
( command
|
||||||
"install-cabal"
|
"install-cabal"
|
||||||
((info
|
((info
|
||||||
((InstallCabalLegacy <$> installOpts) <**> helper)
|
((InstallCabalLegacy <$> installOpts (Just Cabal)) <**> helper)
|
||||||
( progDesc "Install or update cabal"
|
( progDesc "Install or update cabal"
|
||||||
<> footerDoc (Just $ text installCabalFooter)
|
<> footerDoc (Just $ text installCabalFooter)
|
||||||
)
|
)
|
||||||
@ -413,7 +413,7 @@ installParser =
|
|||||||
"ghc"
|
"ghc"
|
||||||
( InstallGHC
|
( InstallGHC
|
||||||
<$> (info
|
<$> (info
|
||||||
(installOpts <**> helper)
|
(installOpts (Just GHC) <**> helper)
|
||||||
( progDesc "Install GHC"
|
( progDesc "Install GHC"
|
||||||
<> footerDoc (Just $ text installGHCFooter)
|
<> footerDoc (Just $ text installGHCFooter)
|
||||||
)
|
)
|
||||||
@ -423,7 +423,7 @@ installParser =
|
|||||||
"cabal"
|
"cabal"
|
||||||
( InstallCabal
|
( InstallCabal
|
||||||
<$> (info
|
<$> (info
|
||||||
(installOpts <**> helper)
|
(installOpts (Just Cabal) <**> helper)
|
||||||
( progDesc "Install Cabal"
|
( progDesc "Install Cabal"
|
||||||
<> footerDoc (Just $ text installCabalFooter)
|
<> footerDoc (Just $ text installCabalFooter)
|
||||||
)
|
)
|
||||||
@ -433,7 +433,7 @@ installParser =
|
|||||||
"hls"
|
"hls"
|
||||||
( InstallHLS
|
( InstallHLS
|
||||||
<$> (info
|
<$> (info
|
||||||
(installOpts <**> helper)
|
(installOpts (Just HLS) <**> helper)
|
||||||
( progDesc "Install haskell-languge-server"
|
( progDesc "Install haskell-languge-server"
|
||||||
<> footerDoc (Just $ text installHLSFooter)
|
<> footerDoc (Just $ text installHLSFooter)
|
||||||
)
|
)
|
||||||
@ -441,7 +441,7 @@ installParser =
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
<|> (Right <$> installOpts)
|
<|> (Right <$> installOpts Nothing)
|
||||||
where
|
where
|
||||||
installHLSFooter :: String
|
installHLSFooter :: String
|
||||||
installHLSFooter = [s|Discussion:
|
installHLSFooter = [s|Discussion:
|
||||||
@ -472,8 +472,8 @@ Examples:
|
|||||||
ghcup install ghc -u https://gitlab.haskell.org/api/v4/projects/1/jobs/artifacts/master/raw/ghc-x86_64-fedora27-linux.tar.xz?job=validate-x86_64-linux-fedora27 head|]
|
ghcup install ghc -u https://gitlab.haskell.org/api/v4/projects/1/jobs/artifacts/master/raw/ghc-x86_64-fedora27-linux.tar.xz?job=validate-x86_64-linux-fedora27 head|]
|
||||||
|
|
||||||
|
|
||||||
installOpts :: Parser InstallOptions
|
installOpts :: Maybe Tool -> Parser InstallOptions
|
||||||
installOpts =
|
installOpts tool =
|
||||||
(\p (u, v) b -> InstallOptions v p u b)
|
(\p (u, v) b -> InstallOptions v p u b)
|
||||||
<$> (optional
|
<$> (optional
|
||||||
(option
|
(option
|
||||||
@ -495,9 +495,9 @@ installOpts =
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
<*> (Just <$> toolVersionArgument)
|
<*> (Just <$> toolVersionArgument True Nothing tool)
|
||||||
)
|
)
|
||||||
<|> ((,) <$> pure Nothing <*> optional toolVersionArgument)
|
<|> (pure (Nothing, Nothing))
|
||||||
)
|
)
|
||||||
<*> flag
|
<*> flag
|
||||||
False
|
False
|
||||||
@ -514,7 +514,7 @@ setParser =
|
|||||||
"ghc"
|
"ghc"
|
||||||
( SetGHC
|
( SetGHC
|
||||||
<$> (info
|
<$> (info
|
||||||
(setOpts <**> helper)
|
(setOpts (Just GHC) <**> helper)
|
||||||
( progDesc "Set GHC version"
|
( progDesc "Set GHC version"
|
||||||
<> footerDoc (Just $ text setGHCFooter)
|
<> footerDoc (Just $ text setGHCFooter)
|
||||||
)
|
)
|
||||||
@ -524,7 +524,7 @@ setParser =
|
|||||||
"cabal"
|
"cabal"
|
||||||
( SetCabal
|
( SetCabal
|
||||||
<$> (info
|
<$> (info
|
||||||
(setOpts <**> helper)
|
(setOpts (Just Cabal) <**> helper)
|
||||||
( progDesc "Set Cabal version"
|
( progDesc "Set Cabal version"
|
||||||
<> footerDoc (Just $ text setCabalFooter)
|
<> footerDoc (Just $ text setCabalFooter)
|
||||||
)
|
)
|
||||||
@ -534,7 +534,7 @@ setParser =
|
|||||||
"hls"
|
"hls"
|
||||||
( SetHLS
|
( SetHLS
|
||||||
<$> (info
|
<$> (info
|
||||||
(setOpts <**> helper)
|
(setOpts (Just HLS) <**> helper)
|
||||||
( progDesc "Set haskell-language-server version"
|
( progDesc "Set haskell-language-server version"
|
||||||
<> footerDoc (Just $ text setHLSFooter)
|
<> footerDoc (Just $ text setHLSFooter)
|
||||||
)
|
)
|
||||||
@ -542,7 +542,7 @@ setParser =
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
<|> (Right <$> setOpts)
|
<|> (Right <$> setOpts Nothing)
|
||||||
where
|
where
|
||||||
setGHCFooter :: String
|
setGHCFooter :: String
|
||||||
setGHCFooter = [s|Discussion:
|
setGHCFooter = [s|Discussion:
|
||||||
@ -559,8 +559,8 @@ setParser =
|
|||||||
Sets the the current haskell-language-server version.|]
|
Sets the the current haskell-language-server version.|]
|
||||||
|
|
||||||
|
|
||||||
setOpts :: Parser SetOptions
|
setOpts :: Maybe Tool -> Parser SetOptions
|
||||||
setOpts = SetOptions <$> optional toolVersionArgument
|
setOpts tool = SetOptions <$> optional (toolVersionArgument False (Just ListInstalled) tool)
|
||||||
|
|
||||||
listOpts :: Parser ListOptions
|
listOpts :: Parser ListOptions
|
||||||
listOpts =
|
listOpts =
|
||||||
@ -592,29 +592,29 @@ rmParser =
|
|||||||
(Left <$> subparser
|
(Left <$> subparser
|
||||||
( command
|
( command
|
||||||
"ghc"
|
"ghc"
|
||||||
(RmGHC <$> (info (rmOpts <**> helper) (progDesc "Remove GHC version")))
|
(RmGHC <$> (info (rmOpts (Just GHC) <**> helper) (progDesc "Remove GHC version")))
|
||||||
<> command
|
<> command
|
||||||
"cabal"
|
"cabal"
|
||||||
( RmCabal
|
( RmCabal
|
||||||
<$> (info (versionParser' <**> helper)
|
<$> (info (versionParser' False (Just ListInstalled) (Just Cabal) <**> helper)
|
||||||
(progDesc "Remove Cabal version")
|
(progDesc "Remove Cabal version")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
<> command
|
<> command
|
||||||
"hls"
|
"hls"
|
||||||
( RmHLS
|
( RmHLS
|
||||||
<$> (info (versionParser' <**> helper)
|
<$> (info (versionParser' False (Just ListInstalled) (Just HLS) <**> helper)
|
||||||
(progDesc "Remove haskell-language-server version")
|
(progDesc "Remove haskell-language-server version")
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
<|> (Right <$> rmOpts)
|
<|> (Right <$> rmOpts Nothing)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
rmOpts :: Parser RmOptions
|
rmOpts :: Maybe Tool -> Parser RmOptions
|
||||||
rmOpts = RmOptions <$> versionArgument
|
rmOpts tool = RmOptions <$> versionArgument False (Just ListInstalled) tool
|
||||||
|
|
||||||
|
|
||||||
changelogP :: Parser ChangeLogOptions
|
changelogP :: Parser ChangeLogOptions
|
||||||
@ -636,7 +636,7 @@ changelogP =
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
<*> optional toolVersionArgument
|
<*> optional (toolVersionArgument True Nothing Nothing)
|
||||||
|
|
||||||
compileP :: Parser CompileCommand
|
compileP :: Parser CompileCommand
|
||||||
compileP = subparser
|
compileP = subparser
|
||||||
@ -765,13 +765,72 @@ toolVersionParser = verP' <|> toolP
|
|||||||
)
|
)
|
||||||
|
|
||||||
-- | same as toolVersionParser, except as an argument.
|
-- | same as toolVersionParser, except as an argument.
|
||||||
toolVersionArgument :: Parser ToolVersion
|
toolVersionArgument :: Bool -> Maybe ListCriteria -> Maybe Tool -> Parser ToolVersion
|
||||||
toolVersionArgument =
|
toolVersionArgument networkSensitive criteria tool =
|
||||||
argument (eitherReader toolVersionEither) (metavar "VERSION|TAG")
|
argument (eitherReader toolVersionEither) (metavar "VERSION|TAG" <> completer tagCompleter <> foldMap (completer . versionCompleter networkSensitive criteria) tool)
|
||||||
|
|
||||||
|
|
||||||
versionArgument :: Parser GHCTargetVersion
|
versionArgument :: Bool -> Maybe ListCriteria -> Maybe Tool -> Parser GHCTargetVersion
|
||||||
versionArgument = argument (eitherReader tVersionEither) (metavar "VERSION")
|
versionArgument networkSensitive criteria tool = argument (eitherReader tVersionEither) (metavar "VERSION" <> foldMap (completer . versionCompleter networkSensitive criteria) tool)
|
||||||
|
|
||||||
|
|
||||||
|
tagCompleter :: Completer
|
||||||
|
tagCompleter =
|
||||||
|
listCompleter [
|
||||||
|
"recommended", "latest"
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
versionCompleter :: Bool -> Maybe ListCriteria -> Tool -> Completer
|
||||||
|
versionCompleter networkSensitive criteria tool =
|
||||||
|
listIOCompleter $ do
|
||||||
|
let
|
||||||
|
loggerConfig =
|
||||||
|
LoggerConfig
|
||||||
|
{ lcPrintDebug = False
|
||||||
|
, colorOutter = mempty
|
||||||
|
, rawOutter = mempty
|
||||||
|
}
|
||||||
|
|
||||||
|
runLogger =
|
||||||
|
myLoggerT loggerConfig
|
||||||
|
|
||||||
|
downloadWithUserSource = do
|
||||||
|
userConf <- runE @'[ JSONError ] ghcupConfigFile
|
||||||
|
getDownloadsF $
|
||||||
|
veitherCont (const GHCupURL) (fromMaybe GHCupURL . uUrlSource) userConf
|
||||||
|
|
||||||
|
mpFreq <-
|
||||||
|
runLogger . runE $
|
||||||
|
platformRequest
|
||||||
|
|
||||||
|
forFold mpFreq $ \pfreq -> do
|
||||||
|
dirs <- getDirs
|
||||||
|
let
|
||||||
|
simpleSettings =
|
||||||
|
Settings False False Never Curl False GHCupURL
|
||||||
|
simpleAppState =
|
||||||
|
AppState simpleSettings dirs defaultKeyBindings
|
||||||
|
runEnv =
|
||||||
|
runLogger . flip runReaderT simpleAppState
|
||||||
|
|
||||||
|
mGhcUpInfo <-
|
||||||
|
runEnv . runE $
|
||||||
|
if networkSensitive then do
|
||||||
|
downloadWithUserSource
|
||||||
|
else
|
||||||
|
catchE
|
||||||
|
(\(FileDoesNotExistError _) -> downloadWithUserSource)
|
||||||
|
readFromCache
|
||||||
|
|
||||||
|
forFold mGhcUpInfo $ \(GHCupInfo _ dls) -> do
|
||||||
|
installedVersions <-
|
||||||
|
runEnv $
|
||||||
|
listVersions dls (Just tool) criteria pfreq
|
||||||
|
|
||||||
|
return $
|
||||||
|
T.unpack . prettyVer . lVer <$> installedVersions
|
||||||
|
|
||||||
|
|
||||||
versionParser :: Parser GHCTargetVersion
|
versionParser :: Parser GHCTargetVersion
|
||||||
versionParser = option
|
versionParser = option
|
||||||
@ -779,10 +838,10 @@ 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' :: Bool -> Maybe ListCriteria -> Maybe Tool -> Parser Version
|
||||||
versionParser' = argument
|
versionParser' networkSensitive criteria tool = argument
|
||||||
(eitherReader (bimap show id . version . T.pack))
|
(eitherReader (first show . version . T.pack))
|
||||||
(metavar "VERSION")
|
(metavar "VERSION" <> foldMap (completer . versionCompleter networkSensitive criteria) tool)
|
||||||
|
|
||||||
|
|
||||||
tagEither :: String -> Either String Tag
|
tagEither :: String -> Either String Tag
|
||||||
@ -792,7 +851,7 @@ tagEither s' = case fmap toLower s' of
|
|||||||
('b':'a':'s':'e':'-':ver') -> case pvp (T.pack ver') of
|
('b':'a':'s':'e':'-':ver') -> case pvp (T.pack ver') of
|
||||||
Right x -> Right (Base x)
|
Right x -> Right (Base x)
|
||||||
Left _ -> Left [i|Invalid PVP version for base #{ver'}|]
|
Left _ -> Left [i|Invalid PVP version for base #{ver'}|]
|
||||||
other -> Left ([i|Unknown tag #{other}|])
|
other -> Left [i|Unknown tag #{other}|]
|
||||||
|
|
||||||
|
|
||||||
tVersionEither :: String -> Either String GHCTargetVersion
|
tVersionEither :: String -> Either String GHCTargetVersion
|
||||||
|
@ -137,30 +137,8 @@ getDownloadsF urlSource = do
|
|||||||
bsExt <- reThrowAll DownloadFailed $ downloadBS uri
|
bsExt <- reThrowAll DownloadFailed $ downloadBS uri
|
||||||
ext <- lE' JSONDecodeError $ bimap show id $ Y.decodeEither' (L.toStrict bsExt)
|
ext <- lE' JSONDecodeError $ bimap show id $ Y.decodeEither' (L.toStrict bsExt)
|
||||||
pure (mergeGhcupInfo base ext)
|
pure (mergeGhcupInfo base ext)
|
||||||
where
|
|
||||||
readFromCache :: (MonadIO m, MonadCatch m, MonadLogger m, MonadReader AppState m)
|
|
||||||
=> Excepts '[JSONError, FileDoesNotExistError] m GHCupInfo
|
|
||||||
readFromCache = do
|
|
||||||
AppState {dirs = Dirs {..}} <- lift ask
|
|
||||||
lift $ $(logWarn)
|
|
||||||
[i|Could not get download info, trying cached version (this may not be recent!)|]
|
|
||||||
let path = view pathL' ghcupURL
|
|
||||||
yaml_file <- (cacheDir </>) <$> urlBaseName path
|
|
||||||
bs <-
|
|
||||||
handleIO' NoSuchThing
|
|
||||||
(\_ -> throwE $ FileDoesNotExistError (toFilePath yaml_file))
|
|
||||||
$ liftIO
|
|
||||||
$ readFile yaml_file
|
|
||||||
lE' JSONDecodeError $ bimap show id $ Y.decodeEither' (L.toStrict bs)
|
|
||||||
|
|
||||||
getBase :: (MonadFail m, MonadIO m, MonadCatch m, MonadLogger m, MonadReader AppState m)
|
where
|
||||||
=> Excepts '[JSONError , FileDoesNotExistError] m GHCupInfo
|
|
||||||
getBase =
|
|
||||||
handleIO (\_ -> readFromCache)
|
|
||||||
$ catchE @_ @'[JSONError, FileDoesNotExistError]
|
|
||||||
(\(DownloadFailed _) -> readFromCache)
|
|
||||||
$ ((reThrowAll @_ @_ @'[JSONError, DownloadFailed] DownloadFailed $ smartDl ghcupURL)
|
|
||||||
>>= (liftE . lE' @_ @_ @'[JSONError] JSONDecodeError . bimap show id . Y.decodeEither' . L.toStrict))
|
|
||||||
|
|
||||||
mergeGhcupInfo :: GHCupInfo -- ^ base to merge with
|
mergeGhcupInfo :: GHCupInfo -- ^ base to merge with
|
||||||
-> GHCupInfo -- ^ extension overwriting the base
|
-> GHCupInfo -- ^ extension overwriting the base
|
||||||
@ -172,6 +150,32 @@ getDownloadsF urlSource = do
|
|||||||
) base
|
) base
|
||||||
in GHCupInfo tr new
|
in GHCupInfo tr new
|
||||||
|
|
||||||
|
|
||||||
|
readFromCache :: (MonadIO m, MonadCatch m, MonadLogger m, MonadReader AppState m)
|
||||||
|
=> Excepts '[JSONError, FileDoesNotExistError] m GHCupInfo
|
||||||
|
readFromCache = do
|
||||||
|
AppState {dirs = Dirs {..}} <- lift ask
|
||||||
|
lift $ $(logWarn)
|
||||||
|
[i|Could not get download info, trying cached version (this may not be recent!)|]
|
||||||
|
let path = view pathL' ghcupURL
|
||||||
|
yaml_file <- (cacheDir </>) <$> urlBaseName path
|
||||||
|
bs <-
|
||||||
|
handleIO' NoSuchThing
|
||||||
|
(\_ -> throwE $ FileDoesNotExistError (toFilePath yaml_file))
|
||||||
|
$ liftIO
|
||||||
|
$ readFile yaml_file
|
||||||
|
lE' JSONDecodeError $ bimap show id $ Y.decodeEither' (L.toStrict bs)
|
||||||
|
|
||||||
|
|
||||||
|
getBase :: (MonadFail m, MonadIO m, MonadCatch m, MonadLogger m, MonadReader AppState m)
|
||||||
|
=> Excepts '[JSONError , FileDoesNotExistError] m GHCupInfo
|
||||||
|
getBase =
|
||||||
|
handleIO (\_ -> readFromCache)
|
||||||
|
$ catchE @_ @'[JSONError, FileDoesNotExistError]
|
||||||
|
(\(DownloadFailed _) -> readFromCache)
|
||||||
|
$ ((reThrowAll @_ @_ @'[JSONError, DownloadFailed] DownloadFailed $ smartDl ghcupURL)
|
||||||
|
>>= (liftE . lE' @_ @_ @'[JSONError] JSONDecodeError . bimap show id . Y.decodeEither' . L.toStrict))
|
||||||
|
where
|
||||||
-- First check if the json file is in the ~/.ghcup/cache dir
|
-- First check if the json file is in the ~/.ghcup/cache dir
|
||||||
-- and check it's access time. If it has been accessed within the
|
-- and check it's access time. If it has been accessed within the
|
||||||
-- last 5 minutes, just reuse it.
|
-- last 5 minutes, just reuse it.
|
||||||
@ -209,8 +213,8 @@ getDownloadsF urlSource = do
|
|||||||
then do
|
then do
|
||||||
accessTime <-
|
accessTime <-
|
||||||
PF.accessTimeHiRes
|
PF.accessTimeHiRes
|
||||||
<$> (liftIO $ PF.getFileStatus (toFilePath json_file))
|
<$> liftIO (PF.getFileStatus (toFilePath json_file))
|
||||||
currentTime <- liftIO $ getPOSIXTime
|
currentTime <- liftIO getPOSIXTime
|
||||||
|
|
||||||
-- access time won't work on most linuxes, but we can try regardless
|
-- access time won't work on most linuxes, but we can try regardless
|
||||||
if (currentTime - accessTime) > 300
|
if (currentTime - accessTime) > 300
|
||||||
|
@ -808,3 +808,12 @@ getVersionInfo v' tool dls =
|
|||||||
% _head
|
% _head
|
||||||
)
|
)
|
||||||
dls
|
dls
|
||||||
|
|
||||||
|
|
||||||
|
-- Gathering monoidal values
|
||||||
|
traverseFold :: (Foldable t, Applicative m, Monoid b) => (a -> m b) -> t a -> m b
|
||||||
|
traverseFold f = foldl (\mb a -> (<>) <$> mb <*> f a) (pure mempty)
|
||||||
|
|
||||||
|
-- | Gathering monoidal values
|
||||||
|
forFold :: (Foldable t, Applicative m, Monoid b) => t a -> (a -> m b) -> m b
|
||||||
|
forFold = flip traverseFold
|
||||||
|
@ -185,9 +185,9 @@ getDirs = do
|
|||||||
ghcupConfigFile :: (MonadIO m)
|
ghcupConfigFile :: (MonadIO m)
|
||||||
=> Excepts '[JSONError] m UserSettings
|
=> Excepts '[JSONError] m UserSettings
|
||||||
ghcupConfigFile = do
|
ghcupConfigFile = do
|
||||||
confDir <- liftIO $ ghcupConfigDir
|
confDir <- liftIO ghcupConfigDir
|
||||||
let file = confDir </> [rel|config.yaml|]
|
let file = confDir </> [rel|config.yaml|]
|
||||||
bs <- liftIO $ handleIO' NoSuchThing (\_ -> pure $ Nothing) $ fmap Just $ readFile file
|
bs <- liftIO $ handleIO' NoSuchThing (\_ -> pure Nothing) $ Just <$> readFile file
|
||||||
case bs of
|
case bs of
|
||||||
Nothing -> pure defaultUserSettings
|
Nothing -> pure defaultUserSettings
|
||||||
Just bs' -> lE' JSONDecodeError . bimap show id . Y.decodeEither' . L.toStrict $ bs'
|
Just bs' -> lE' JSONDecodeError . bimap show id . Y.decodeEither' . L.toStrict $ bs'
|
||||||
|
Loading…
Reference in New Issue
Block a user