-- Copyright (c) 2020, 2024 Shayne Fletcher. All rights reserved. -- SPDX-License-Identifier: BSD-3-Clause. {-# LANGUAGE CPP #-} {-# LANGUAGE NamedFieldPuns #-} import Control.Monad.Extra #if __GLASGOW_HASKELL__ < 906 import Control.Applicative (liftA2) #endif import Data.Bifunctor import Data.List.Extra import Data.Time.Calendar import Data.Time.Clock import qualified Options.Applicative as Opts import System.Exit import System.IO.Extra import System.Process.Extra main :: IO () main = do let opts = Opts.info (parseOptions Opts.<**> Opts.helper) ( Opts.fullDesc <> Opts.progDesc "Build and test ghc-lib-parser-ex." <> Opts.header "CI - CI script for ghc-lib-parser-ex" ) options <- Opts.execParser opts buildTestDist options buildTestDist :: Options -> IO () buildTestDist Options {versionTag = userGivenTag, noBuilds} = do assignVersionPatchCabal userGivenTag system_ "cabal sdist -o ." when noBuilds exitSuccess system_ "cabal build lib:ghc-lib-parser-ex --ghc-options=-j" system_ "cabal test test:ghc-lib-parser-ex-test --ghc-options=-j --test-show-details=direct --test-options=\"--color always\"" #if __GLASGOW_HASKELL__ == 808 && \ (__GLASGOW_HASKELL_PATCHLEVEL1__ == 1 || __GLASGOW_HASKELL_PATCHLEVEL1__ == 2) && \ defined (mingw32_HOST_OS) -- https://gitlab.haskell.org/ghc/ghc/issues/17599 #else system_ "cabal exec -- ghc -ignore-dot-ghci -package=ghc-lib-parser-ex -e \"print 1\"" #endif assignVersionPatchCabal :: Maybe String -> IO () assignVersionPatchCabal userTag = do version <- mkVersion userTag patchCabal version contents <- readFile' "ghc-lib-parser-ex.cabal" putStrLn contents hFlush stdout where mkVersion :: Maybe String -> IO String mkVersion = maybe (do UTCTime day _ <- getCurrentTime; pure $ genVersionStr day) pure genVersionStr :: Day -> String genVersionStr day = "0." ++ replace "-" "" (showGregorian day) patchCabal :: String -> IO () patchCabal version = do putStrLn "Patching cabal:" putStrLn $ "- version " ++ version writeFile "ghc-lib-parser-ex.cabal" . replace "version: 0.1.0" ("version: " ++ version) =<< readFile' "ghc-lib-parser-ex.cabal" let series | Just (major, Just (minor, _)) <- second (stripInfix ".") <$> stripInfix "." version = liftA2 (,) (maybeRead major) (maybeRead minor) | otherwise = Nothing case series of Just (major, minor) -> do let (lower, upper, family) = bounds (major, minor) putStrLn $ "- ghc >= " ++ lower ++ " && ghc < " ++ upper putStrLn $ "- ghc-lib-parser " ++ family writeFile "ghc-lib-parser-ex.cabal" . replace "9.0.0" lower . replace "9.1.0" upper . replace "9.0.*" family =<< readFile' "ghc-lib-parser-ex.cabal" Nothing -> do let ghcLibParserVersion = version putStrLn $ "- ghc-lib-parser " ++ ghcLibParserVersion writeFile "ghc-lib-parser-ex.cabal" . replace buildDependsSection ( unlines [ " build-depends:", " ghc-lib-parser == " ++ ghcLibParserVersion, " -- pseduo use of flags to suppress cabal check warnings", " if flag(auto)", " if flag(no-ghc-lib)" ] ) =<< readFile' "ghc-lib-parser-ex.cabal" where maybeRead :: String -> Maybe Int maybeRead s | [(x, "")] <- reads s = Just x | otherwise = Nothing buildDependsSection :: String buildDependsSection = unlines [ " if flag(auto) && impl(ghc >= 9.0.0) && impl(ghc < 9.1.0)", " build-depends:", " ghc == 9.0.*,", " ghc-boot-th,", " ghc-boot", " else", " if flag(auto)", " build-depends:", " ghc-lib-parser == 9.0.*", " else", " if flag(no-ghc-lib)", " build-depends:", " ghc == 9.0.*,", " ghc-boot-th,", " ghc-boot", " else", " build-depends:", " ghc-lib-parser == 9.0.*" ] bounds :: (Int, Int) -> (String, String, String) bounds (major, minor) = let lower = if lower' == "9.2.0" then "9.2.2" else lower' upper = upper' family = family' in (lower, upper, family) where lower' = show major ++ "." ++ show minor ++ ".0" upper' = show major ++ "." ++ show (minor + 1) ++ ".0" family' = show major ++ "." ++ show minor ++ ".*" data Options = Options { versionTag :: Maybe String, -- If 'Just _' use this as the version (e.g. "8.8.1.20191204") noBuilds :: Bool -- Don't build or run tests } deriving (Show) parseOptions :: Opts.Parser Options parseOptions = Options <$> Opts.optional ( Opts.strOption (Opts.long "version-tag" <> Opts.help "Set version") ) <*> Opts.switch (Opts.long "no-builds" <> Opts.help "If enabled, stop after producing sdists")