2022-03-01 00:02:22 +00:00
|
|
|
{-# LANGUAGE CPP #-}
|
|
|
|
{-# LANGUAGE DataKinds #-}
|
|
|
|
{-# LANGUAGE FlexibleContexts #-}
|
|
|
|
{-# LANGUAGE QuasiQuotes #-}
|
|
|
|
{-# LANGUAGE TemplateHaskell #-}
|
|
|
|
{-# LANGUAGE TypeApplications #-}
|
|
|
|
{-# LANGUAGE ViewPatterns #-}
|
|
|
|
{-# LANGUAGE OverloadedStrings #-}
|
|
|
|
|
|
|
|
module Generate where
|
|
|
|
|
2022-03-08 21:22:36 +00:00
|
|
|
import GHCup
|
2022-03-01 00:02:22 +00:00
|
|
|
import GHCup.Download
|
|
|
|
import GHCup.Errors
|
|
|
|
import GHCup.Types
|
|
|
|
import GHCup.Types.Optics
|
|
|
|
import GHCup.Utils
|
2022-03-08 13:59:14 +00:00
|
|
|
|
2022-03-01 00:02:22 +00:00
|
|
|
|
|
|
|
import Codec.Archive
|
2022-03-08 21:22:36 +00:00
|
|
|
import Control.Exception.Safe hiding ( handle )
|
2022-03-01 00:02:22 +00:00
|
|
|
import Control.Monad
|
|
|
|
import Control.Monad.IO.Class
|
|
|
|
import Control.Monad.Reader.Class
|
|
|
|
import Control.Monad.Trans.Resource ( runResourceT
|
|
|
|
, MonadUnliftIO
|
|
|
|
)
|
2022-03-08 13:59:14 +00:00
|
|
|
import qualified Data.Aeson.Encode.Pretty as Aeson
|
2022-03-01 00:02:22 +00:00
|
|
|
import Data.ByteString ( ByteString )
|
|
|
|
import Data.Either
|
|
|
|
import Data.Maybe
|
|
|
|
import Data.List
|
|
|
|
import Data.Map.Strict ( Map )
|
|
|
|
import Data.Versions
|
|
|
|
import Haskus.Utils.Variant.Excepts
|
|
|
|
import System.Exit
|
2022-03-08 21:22:36 +00:00
|
|
|
import System.IO
|
2022-03-01 00:02:22 +00:00
|
|
|
import Text.Regex.Posix
|
|
|
|
import GHCup.Utils.String.QQ
|
|
|
|
|
2022-03-08 13:59:14 +00:00
|
|
|
import qualified Data.ByteString.Lazy as BSL
|
2022-03-01 00:02:22 +00:00
|
|
|
import qualified Data.Map.Strict as M
|
|
|
|
import qualified Data.Text as T
|
|
|
|
import qualified Data.Yaml.Pretty as YAML
|
|
|
|
import qualified Text.Megaparsec as MP
|
|
|
|
|
2022-03-08 13:59:14 +00:00
|
|
|
data Format = FormatJSON
|
|
|
|
| FormatYAML
|
2022-03-01 00:02:22 +00:00
|
|
|
|
2022-03-08 13:59:14 +00:00
|
|
|
data Output
|
|
|
|
= FileOutput FilePath -- optsparse-applicative doesn't handle ByteString correctly anyway
|
|
|
|
| StdOut
|
2022-03-01 00:02:22 +00:00
|
|
|
|
|
|
|
type HlsGhcVersions = Map Version (Map Architecture (Map Platform Version))
|
|
|
|
|
2022-03-08 21:22:36 +00:00
|
|
|
generateHLSGhc :: ( MonadFail m
|
|
|
|
, MonadMask m
|
|
|
|
, Monad m
|
|
|
|
, MonadReader env m
|
|
|
|
, HasSettings env
|
|
|
|
, HasDirs env
|
|
|
|
, HasLog env
|
|
|
|
, MonadThrow m
|
|
|
|
, MonadIO m
|
|
|
|
, MonadUnliftIO m
|
|
|
|
, HasGHCupInfo env
|
|
|
|
)
|
|
|
|
=> Format
|
|
|
|
-> Output
|
|
|
|
-> m ExitCode
|
|
|
|
generateHLSGhc format output = do
|
|
|
|
GHCupInfo { _ghcupDownloads = dls } <- getGHCupInfo
|
2022-03-01 00:02:22 +00:00
|
|
|
let hlses = dls M.! HLS
|
|
|
|
r <- forM hlses $ \(_viArch -> archs) ->
|
|
|
|
forM archs $ \plats ->
|
|
|
|
forM plats $ \(head . M.toList -> (_, dli)) -> do
|
|
|
|
VRight r <- runResourceT . runE
|
|
|
|
@'[DigestError
|
|
|
|
, GPGError
|
|
|
|
, DownloadFailed
|
|
|
|
, UnknownArchive
|
|
|
|
, ArchiveResult
|
|
|
|
] $ do
|
|
|
|
fp <- liftE $ downloadCached dli Nothing
|
|
|
|
files <- liftE $ getArchiveFiles fp
|
|
|
|
let regex = makeRegexOpts compExtended execBlank ([s|^haskell-language-server-([0-9]+\.)*([0-9]+)$|] :: ByteString)
|
|
|
|
let ghcs = rights $ MP.parse version' ""
|
|
|
|
. T.pack
|
|
|
|
. fromJust
|
|
|
|
. stripPrefix "haskell-language-server-"
|
|
|
|
<$> filter (match regex) files
|
|
|
|
pure ghcs
|
|
|
|
pure r
|
2022-03-08 13:59:14 +00:00
|
|
|
let w = case format of
|
|
|
|
FormatYAML -> BSL.fromStrict $ YAML.encodePretty YAML.defConfig r
|
|
|
|
FormatJSON -> Aeson.encodePretty r
|
|
|
|
case output of
|
|
|
|
StdOut -> liftIO $ BSL.putStr w
|
|
|
|
FileOutput f -> liftIO $ BSL.writeFile f w
|
2022-03-01 00:02:22 +00:00
|
|
|
pure ExitSuccess
|
2022-03-08 21:22:36 +00:00
|
|
|
|
|
|
|
|
|
|
|
generateTable :: ( MonadFail m
|
|
|
|
, MonadMask m
|
|
|
|
, Monad m
|
|
|
|
, MonadReader env m
|
|
|
|
, HasSettings env
|
|
|
|
, HasDirs env
|
|
|
|
, HasLog env
|
|
|
|
, MonadThrow m
|
|
|
|
, MonadIO m
|
|
|
|
, HasPlatformReq env
|
|
|
|
, HasGHCupInfo env
|
|
|
|
, MonadUnliftIO m
|
|
|
|
)
|
|
|
|
=> Output
|
|
|
|
-> m ExitCode
|
|
|
|
generateTable output = do
|
|
|
|
handle <- case output of
|
|
|
|
StdOut -> pure stdout
|
|
|
|
FileOutput fp -> liftIO $ openFile fp WriteMode
|
|
|
|
|
|
|
|
forM_ [GHC,Cabal,HLS,Stack] $ \tool -> do
|
|
|
|
liftIO $ hPutStrLn handle $ "<table>"
|
|
|
|
liftIO $ hPutStrLn handle $ "<thead><tr><th>" <> show tool <> " Version</th><th>Tags</th></tr></thead>"
|
|
|
|
liftIO $ hPutStrLn handle $ "<tbody>"
|
|
|
|
vers <- listVersions (Just tool) Nothing
|
|
|
|
forM_ (filter (\ListResult{..} -> not lStray) vers) $ \ListResult{..} -> do
|
|
|
|
liftIO $ hPutStrLn handle $
|
|
|
|
"<tr><td>"
|
|
|
|
<> T.unpack (prettyVer lVer)
|
|
|
|
<> "</td><td>"
|
|
|
|
<> intercalate ", " (filter (/= "") . fmap printTag $ sort lTag)
|
|
|
|
<> "</td></tr>"
|
|
|
|
pure ()
|
|
|
|
liftIO $ hPutStrLn handle $ "</tbody>"
|
|
|
|
liftIO $ hPutStrLn handle $ "</table>"
|
|
|
|
liftIO $ hPutStrLn handle $ ""
|
|
|
|
pure ExitSuccess
|
|
|
|
where
|
|
|
|
printTag Recommended = "<span style=\"color:green\">recommended</span>"
|
|
|
|
printTag Latest = "<span style=\"color:blue\">latest</span>"
|
|
|
|
printTag Prerelease = "<span style=\"color:red\">prerelease</span>"
|
|
|
|
printTag (Base pvp'') = "base-" ++ T.unpack (prettyPVP pvp'')
|
|
|
|
printTag (UnknownTag t ) = t
|
|
|
|
printTag Old = ""
|