{-# LANGUAGE MultiWayIf        #-}
{-# LANGUAGE NamedFieldPuns    #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards   #-}
module HaskellCI.GitHub (
    makeGitHub,
    githubHeader,
) where

import HaskellCI.Prelude

import Control.Applicative (optional)

import qualified Crypto.Hash.SHA256              as SHA256
import qualified Data.Attoparsec.Text            as Atto
import qualified Data.Binary                     as Binary
import qualified Data.Binary.Put                 as Binary
import qualified Data.ByteString.Base16          as Base16
import qualified Data.ByteString.Char8           as BS8
import qualified Data.Map.Strict                 as Map
import qualified Data.Set                        as S
import qualified Data.Text                       as T
import qualified Distribution.Fields.Pretty      as C
import qualified Distribution.Package            as C
import qualified Distribution.Pretty             as C
import qualified Distribution.Types.VersionRange as C
import qualified Distribution.Version            as C

import Cabal.Project
import HaskellCI.Auxiliary
import HaskellCI.Compiler
import HaskellCI.Config
import HaskellCI.Config.ConstraintSet
import HaskellCI.Config.Docspec
import HaskellCI.Config.Doctest
import HaskellCI.Config.HLint
import HaskellCI.Config.Installed
import HaskellCI.Config.Jobs
import HaskellCI.Config.PackageScope
import HaskellCI.Config.Ubuntu
import HaskellCI.Config.Validity
import HaskellCI.Cabal
import HaskellCI.GitConfig
import HaskellCI.GitHub.Yaml
import HaskellCI.HeadHackage
import HaskellCI.Jobs
import HaskellCI.List
import HaskellCI.MonadErr
import HaskellCI.Package
import HaskellCI.Sh
import HaskellCI.ShVersionRange
import HaskellCI.Tools
import HaskellCI.VersionInfo

-- $setup
-- >>> :set -XOverloadedStrings

-------------------------------------------------------------------------------
-- GitHub header
-------------------------------------------------------------------------------

githubHeader :: Bool -> [String] -> [String]
githubHeader :: Bool -> [[Char]] -> [[Char]]
githubHeader Bool
insertVersion [[Char]]
argv =
    [ [Char]
"This GitHub workflow config has been generated by a script via"
    , [Char]
""
    , [Char]
"  haskell-ci " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [[Char]] -> [Char]
unwords [ [Char]
"'" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
a [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"'" | [Char]
a <- [[Char]]
argv ]
    , [Char]
""
    , [Char]
"To regenerate the script (for example after adjusting tested-with) run"
    , [Char]
""
    , [Char]
"  haskell-ci regenerate"
    , [Char]
""
    , [Char]
"For more information, see https://github.com/haskell-CI/haskell-ci"
    , [Char]
""
    ] [[Char]] -> [[Char]] -> [[Char]]
forall a. [a] -> [a] -> [a]
++
    [[Char]]
verlines [[Char]] -> [[Char]] -> [[Char]]
forall a. [a] -> [a] -> [a]
++
    [ [Char]
"REGENDATA " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ if Bool
insertVersion then ([Char], [[Char]]) -> [Char]
forall a. Show a => a -> [Char]
show ([Char]
haskellCIVerStr, [[Char]]
argv) else [[Char]] -> [Char]
forall a. Show a => a -> [Char]
show [[Char]]
argv
    , [Char]
""
    ]
  where
    verlines :: [[Char]]
verlines
        | Bool
insertVersion = [ [Char]
"version: " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
haskellCIVerStr , [Char]
"" ]
        | Bool
otherwise     = []

-------------------------------------------------------------------------------
-- GitHub
-------------------------------------------------------------------------------

{-
GitHub Actions–specific notes:

* We use -j2 for parallelism, as GitHub's virtual machines use 2 cores, per
  https://docs.github.com/en/free-pro-team@latest/actions/reference/specifications-for-github-hosted-runners#supported-runners-and-hardware-resources.
-}

makeGitHub
    :: [String]
    -> Config
    -> GitConfig
    -> Project URI Void Package
    -> JobVersions
    -> Either HsCiError GitHub
makeGitHub :: [[Char]]
-> Config
-> GitConfig
-> Project URI Void Package
-> JobVersions
-> Either HsCiError GitHub
makeGitHub [[Char]]
_argv config :: Config
config@Config {Bool
Natural
[Char]
[[Char]]
[PrettyField ()]
[PackageName]
[Installed]
[ConstraintSet]
Maybe [Char]
Maybe Version
Maybe Jobs
Set [Char]
Set Fold
Map Version [Char]
Version
VersionRange
Ubuntu
PackageScope
HLintConfig
DoctestConfig
DocspecConfig
CopyFields
Components
TestedWithJobs
cfgCabalInstallVersion :: Maybe Version
cfgJobs :: Maybe Jobs
cfgUbuntu :: Ubuntu
cfgTestedWith :: TestedWithJobs
cfgEnabledJobs :: VersionRange
cfgCopyFields :: CopyFields
cfgLocalGhcOptions :: [[Char]]
cfgSubmodules :: Bool
cfgCache :: Bool
cfgInstallDeps :: Bool
cfgInstalled :: [Installed]
cfgTests :: VersionRange
cfgRunTests :: VersionRange
cfgBenchmarks :: VersionRange
cfgHaddock :: VersionRange
cfgHaddockComponents :: Components
cfgNoTestsNoBench :: VersionRange
cfgUnconstrainted :: VersionRange
cfgHeadHackage :: VersionRange
cfgHeadHackageOverride :: Bool
cfgGhcjsTests :: Bool
cfgGhcjsTools :: [PackageName]
cfgTestOutputDirect :: Bool
cfgCheck :: Bool
cfgOnlyBranches :: [[Char]]
cfgIrcChannels :: [[Char]]
cfgIrcNickname :: Maybe [Char]
cfgIrcPassword :: Maybe [Char]
cfgIrcIfInOriginRepo :: Bool
cfgEmailNotifications :: Bool
cfgProjectName :: Maybe [Char]
cfgFolds :: Set Fold
cfgGhcHead :: Bool
cfgPostgres :: Bool
cfgGoogleChrome :: Bool
cfgEnv :: Map Version [Char]
cfgAllowFailures :: VersionRange
cfgLastInSeries :: Bool
cfgLinuxJobs :: VersionRange
cfgMacosJobs :: VersionRange
cfgGhcupCabal :: Bool
cfgGhcupJobs :: VersionRange
cfgGhcupVersion :: Version
cfgApt :: Set [Char]
cfgTravisPatches :: [[Char]]
cfgGitHubPatches :: [[Char]]
cfgInsertVersion :: Bool
cfgErrorMissingMethods :: PackageScope
cfgDoctest :: DoctestConfig
cfgDocspec :: DocspecConfig
cfgHLint :: HLintConfig
cfgConstraintSets :: [ConstraintSet]
cfgRawProject :: [PrettyField ()]
cfgRawTravis :: [Char]
cfgGitHubActionName :: Maybe [Char]
cfgTimeoutMinutes :: Natural
cfgCabalInstallVersion :: Config -> Maybe Version
cfgJobs :: Config -> Maybe Jobs
cfgUbuntu :: Config -> Ubuntu
cfgTestedWith :: Config -> TestedWithJobs
cfgEnabledJobs :: Config -> VersionRange
cfgCopyFields :: Config -> CopyFields
cfgLocalGhcOptions :: Config -> [[Char]]
cfgSubmodules :: Config -> Bool
cfgCache :: Config -> Bool
cfgInstallDeps :: Config -> Bool
cfgInstalled :: Config -> [Installed]
cfgTests :: Config -> VersionRange
cfgRunTests :: Config -> VersionRange
cfgBenchmarks :: Config -> VersionRange
cfgHaddock :: Config -> VersionRange
cfgHaddockComponents :: Config -> Components
cfgNoTestsNoBench :: Config -> VersionRange
cfgUnconstrainted :: Config -> VersionRange
cfgHeadHackage :: Config -> VersionRange
cfgHeadHackageOverride :: Config -> Bool
cfgGhcjsTests :: Config -> Bool
cfgGhcjsTools :: Config -> [PackageName]
cfgTestOutputDirect :: Config -> Bool
cfgCheck :: Config -> Bool
cfgOnlyBranches :: Config -> [[Char]]
cfgIrcChannels :: Config -> [[Char]]
cfgIrcNickname :: Config -> Maybe [Char]
cfgIrcPassword :: Config -> Maybe [Char]
cfgIrcIfInOriginRepo :: Config -> Bool
cfgEmailNotifications :: Config -> Bool
cfgProjectName :: Config -> Maybe [Char]
cfgFolds :: Config -> Set Fold
cfgGhcHead :: Config -> Bool
cfgPostgres :: Config -> Bool
cfgGoogleChrome :: Config -> Bool
cfgEnv :: Config -> Map Version [Char]
cfgAllowFailures :: Config -> VersionRange
cfgLastInSeries :: Config -> Bool
cfgLinuxJobs :: Config -> VersionRange
cfgMacosJobs :: Config -> VersionRange
cfgGhcupCabal :: Config -> Bool
cfgGhcupJobs :: Config -> VersionRange
cfgGhcupVersion :: Config -> Version
cfgApt :: Config -> Set [Char]
cfgTravisPatches :: Config -> [[Char]]
cfgGitHubPatches :: Config -> [[Char]]
cfgInsertVersion :: Config -> Bool
cfgErrorMissingMethods :: Config -> PackageScope
cfgDoctest :: Config -> DoctestConfig
cfgDocspec :: Config -> DocspecConfig
cfgHLint :: Config -> HLintConfig
cfgConstraintSets :: Config -> [ConstraintSet]
cfgRawProject :: Config -> [PrettyField ()]
cfgRawTravis :: Config -> [Char]
cfgGitHubActionName :: Config -> Maybe [Char]
cfgTimeoutMinutes :: Config -> Natural
..} GitConfig
gitconfig Project URI Void Package
prj jobs :: JobVersions
jobs@JobVersions {Set CompilerVersion
allVersions :: Set CompilerVersion
linuxVersions :: Set CompilerVersion
macosVersions :: Set CompilerVersion
allVersions :: JobVersions -> Set CompilerVersion
linuxVersions :: JobVersions -> Set CompilerVersion
macosVersions :: JobVersions -> Set CompilerVersion
..} = do
    let envEnv :: Map [Char] [Char]
envEnv = [([Char], [Char])] -> Map [Char] [Char]
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList
            [ ([Char]
"HCNAME", [Char]
"${{ matrix.compiler }}")         -- e.g. ghc-8.8.4
            , ([Char]
"HCKIND", [Char]
"${{ matrix.compilerKind }}")     --      ghc
            , ([Char]
"HCVER",  [Char]
"${{ matrix.compilerVersion }}")  --      8.8.4
            ]

    -- Validity checks
    Config -> JobVersions -> Either HsCiError ()
forall (m :: * -> *).
MonadErr HsCiError m =>
Config -> JobVersions -> m ()
checkConfigValidity Config
config JobVersions
jobs
    Bool -> Either HsCiError () -> Either HsCiError ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Bool
cfgSubmodules Bool -> Bool -> Bool
&& Ubuntu
cfgUbuntu Ubuntu -> Ubuntu -> Bool
forall a. Ord a => a -> a -> Bool
< Ubuntu
Focal) (Either HsCiError () -> Either HsCiError ())
-> Either HsCiError () -> Either HsCiError ()
forall a b. (a -> b) -> a -> b
$
        HsCiError -> Either HsCiError ()
forall a. HsCiError -> Either HsCiError a
forall e (m :: * -> *) a. MonadErr e m => e -> m a
throwErr (HsCiError -> Either HsCiError ())
-> HsCiError -> Either HsCiError ()
forall a b. (a -> b) -> a -> b
$ [Char] -> HsCiError
ValidationError ([Char] -> HsCiError) -> [Char] -> HsCiError
forall a b. (a -> b) -> a -> b
$ [[Char]] -> [Char]
unwords
            [ [Char]
"Using submodules on the GitHub Actions backend requires"
            , [Char]
"Ubuntu 20.04 (Focal Fossa) or later."
            ]

    [GitHubStep]
steps <- [Either HsCiError GitHubStep] -> Either HsCiError [GitHubStep]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
forall (m :: * -> *) a. Monad m => [m a] -> m [a]
sequence ([Either HsCiError GitHubStep] -> Either HsCiError [GitHubStep])
-> [Either HsCiError GitHubStep] -> Either HsCiError [GitHubStep]
forall a b. (a -> b) -> a -> b
$ ListBuilder (Either HsCiError GitHubStep) ()
-> [Either HsCiError GitHubStep]
forall x. ListBuilder x () -> [x]
buildList (ListBuilder (Either HsCiError GitHubStep) ()
 -> [Either HsCiError GitHubStep])
-> ListBuilder (Either HsCiError GitHubStep) ()
-> [Either HsCiError GitHubStep]
forall a b. (a -> b) -> a -> b
$ do
        -- This have to be first, since the packages we install depend on
        -- whether we need GHCJS or not.
        Bool
-> ListBuilder (Either HsCiError GitHubStep) ()
-> ListBuilder (Either HsCiError GitHubStep) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
anyGHCJS (ListBuilder (Either HsCiError GitHubStep) ()
 -> ListBuilder (Either HsCiError GitHubStep) ())
-> ListBuilder (Either HsCiError GitHubStep) ()
-> ListBuilder (Either HsCiError GitHubStep) ()
forall a b. (a -> b) -> a -> b
$ [Char]
-> Map [Char] [Char]
-> ShM ()
-> ListBuilder (Either HsCiError GitHubStep) ()
githubRun' [Char]
"Set GHCJS environment variables" Map [Char] [Char]
envEnv (ShM () -> ListBuilder (Either HsCiError GitHubStep) ())
-> ShM () -> ListBuilder (Either HsCiError GitHubStep) ()
forall a b. (a -> b) -> a -> b
$ [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh ([Char] -> ShM ()) -> [Char] -> ShM ()
forall a b. (a -> b) -> a -> b
$ [Char] -> [[Char]] -> [Char]
forall a. [a] -> [[a]] -> [a]
intercalate [Char]
"\n"
            [ [Char]
"if [ $HCKIND = ghcjs ]; then"
            , [Char] -> [Char] -> [Char]
tell_env' [Char]
"GHCJS" [Char]
"true"
            , [Char] -> [Char] -> [Char]
tell_env' [Char]
"GHCJSARITH" [Char]
"1"
            , [Char]
"else"
            , [Char] -> [Char] -> [Char]
tell_env' [Char]
"GHCJS" [Char]
"false"
            , [Char] -> [Char] -> [Char]
tell_env' [Char]
"GHCJSARITH" [Char]
"0"
            , [Char]
"fi"
            ]

        [Char]
-> Map [Char] [Char]
-> ShM ()
-> ListBuilder (Either HsCiError GitHubStep) ()
githubRun' [Char]
"apt" Map [Char] [Char]
envEnv (ShM () -> ListBuilder (Either HsCiError GitHubStep) ())
-> ShM () -> ListBuilder (Either HsCiError GitHubStep) ()
forall a b. (a -> b) -> a -> b
$ do
            [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh [Char]
"apt-get update"
            let corePkgs :: [String]
                corePkgs :: [[Char]]
corePkgs =
                    [ [Char]
"gnupg"
                    , [Char]
"ca-certificates"
                    , [Char]
"dirmngr"
                    , [Char]
"curl"
                    , [Char]
"git"
                    , [Char]
"software-properties-common"
                    , [Char]
"libtinfo5"
                    ] [[Char]] -> [[Char]] -> [[Char]]
forall a. [a] -> [a] -> [a]
++
                    -- Installing libnuma-dev is required to work around
                    -- https://gitlab.haskell.org/haskell/ghcup-hs/-/blob/b0522507be6fa991a819aaf22f9a551757380821/README.md#libnuma-required
                    [ [Char]
"libnuma-dev"
                    | Version -> CompilerVersion
GHC ([Int] -> Version
C.mkVersion [Int
8,Int
4,Int
4]) CompilerVersion -> Set CompilerVersion -> Bool
forall a. Eq a => a -> Set a -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` Set CompilerVersion
allVersions
                    , Version -> CompilerVersion
GHC ([Int] -> Version
C.mkVersion [Int
8,Int
4,Int
4]) CompilerVersion -> (CompilerVersion -> Bool) -> Bool
forall a b. a -> (a -> b) -> b
& CompilerVersion -> Bool
isGHCUP
                    ]
            [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh ([Char] -> ShM ()) -> [Char] -> ShM ()
forall a b. (a -> b) -> a -> b
$ [Char]
"apt-get install -y --no-install-recommends " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [[Char]] -> [Char]
unwords [[Char]]
corePkgs

            let installGhcup :: ShM ()
                installGhcup :: ShM ()
installGhcup = do
                    let ghcupVer :: [Char]
ghcupVer = Version -> [Char]
forall a. Pretty a => a -> [Char]
C.prettyShow Version
cfgGhcupVersion
                    [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh ([Char] -> ShM ()) -> [Char] -> ShM ()
forall a b. (a -> b) -> a -> b
$ [Char]
"mkdir -p \"$HOME/.ghcup/bin\""
                    [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh ([Char] -> ShM ()) -> [Char] -> ShM ()
forall a b. (a -> b) -> a -> b
$ [Char]
"curl -sL https://downloads.haskell.org/ghcup/" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
ghcupVer [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"/x86_64-linux-ghcup-" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
ghcupVer [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" > \"$HOME/.ghcup/bin/ghcup\""
                    [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh ([Char] -> ShM ()) -> [Char] -> ShM ()
forall a b. (a -> b) -> a -> b
$ [Char]
"chmod a+x \"$HOME/.ghcup/bin/ghcup\""

                    -- if any job uses prereleases, add release channel unconditionally. (HEADHACKAGE variable is set later)
                    Bool -> ShM () -> ShM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Bool
anyJobUsesPreviewGHC Bool -> Bool -> Bool
|| Maybe Version -> Bool
previewCabal Maybe Version
cfgCabalInstallVersion) (ShM () -> ShM ()) -> ShM () -> ShM ()
forall a b. (a -> b) -> a -> b
$
                      [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh [Char]
"\"$HOME/.ghcup/bin/ghcup\" config add-release-channel https://raw.githubusercontent.com/haskell/ghcup-metadata/master/ghcup-prereleases-0.0.7.yaml;"

                installGhcupCabal :: ShM ()
                installGhcupCabal :: ShM ()
installGhcupCabal =
                    [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh ([Char] -> ShM ()) -> [Char] -> ShM ()
forall a b. (a -> b) -> a -> b
$ [Char]
"\"$HOME/.ghcup/bin/ghcup\" install cabal " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
cabalFullVer [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" || (cat \"$HOME\"/.ghcup/logs/*.* && false)"

            [Sh]
hvrppa <- ShM () -> ShM [Sh]
forall e (m :: * -> *).
(MonadErr e m, FromHsCiError e) =>
ShM () -> m [Sh]
runSh (ShM () -> ShM [Sh]) -> ShM () -> ShM [Sh]
forall a b. (a -> b) -> a -> b
$ do
                [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh [Char]
"apt-add-repository -y 'ppa:hvr/ghc'"
                Bool -> ShM () -> ShM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
anyGHCJS (ShM () -> ShM ()) -> ShM () -> ShM ()
forall a b. (a -> b) -> a -> b
$ do
                    CompilerRange -> [Char] -> ShM ()
sh_if CompilerRange
RangeGHCJS [Char]
"apt-add-repository -y 'ppa:hvr/ghcjs'"
                    CompilerRange -> [Char] -> ShM ()
sh_if CompilerRange
RangeGHCJS [Char]
"curl -sSL \"https://deb.nodesource.com/gpgkey/nodesource.gpg.key\" | apt-key add -"
                    CompilerRange -> [Char] -> ShM ()
sh_if CompilerRange
RangeGHCJS ([Char] -> ShM ()) -> [Char] -> ShM ()
forall a b. (a -> b) -> a -> b
$ [Char]
"apt-add-repository -y 'deb https://deb.nodesource.com/node_10.x " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
ubuntuVer [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" main'"
                [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh [Char]
"apt-get update"
                let basePackages :: [[Char]]
basePackages  = [[Char]
"\"$HCNAME\"" ] [[Char]] -> [[Char]] -> [[Char]]
forall a. [a] -> [a] -> [a]
++ [ [Char]
"cabal-install-" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
cabalVer | Bool -> Bool
not Bool
cfgGhcupCabal ] [[Char]] -> [[Char]] -> [[Char]]
forall a. [a] -> [a] -> [a]
++ Set [Char] -> [[Char]]
forall a. Set a -> [a]
S.toList Set [Char]
cfgApt
                    ghcjsPackages :: [[Char]]
ghcjsPackages = [[Char]
"ghc-8.4.4", [Char]
"nodejs"]
                    baseInstall :: [Char]
baseInstall   = [Char]
"apt-get install -y " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [[Char]] -> [Char]
unwords [[Char]]
basePackages
                    ghcjsInstall :: [Char]
ghcjsInstall  = [Char]
"apt-get install -y " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [[Char]] -> [Char]
unwords ([[Char]]
basePackages [[Char]] -> [[Char]] -> [[Char]]
forall a. [a] -> [a] -> [a]
++ [[Char]]
ghcjsPackages)
                if Bool
anyGHCJS
                    then CompilerRange -> [Char] -> [Char] -> ShM ()
if_then_else CompilerRange
RangeGHCJS [Char]
ghcjsInstall [Char]
baseInstall
                    else [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh [Char]
baseInstall
                Bool -> ShM () -> ShM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
cfgGhcupCabal (ShM () -> ShM ()) -> ShM () -> ShM ()
forall a b. (a -> b) -> a -> b
$ do
                    ShM ()
installGhcup
                    ShM ()
installGhcupCabal

            [Sh]
ghcup <- ShM () -> ShM [Sh]
forall e (m :: * -> *).
(MonadErr e m, FromHsCiError e) =>
ShM () -> m [Sh]
runSh (ShM () -> ShM [Sh]) -> ShM () -> ShM [Sh]
forall a b. (a -> b) -> a -> b
$ do
                ShM ()
installGhcup

                [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh ([Char] -> ShM ()) -> [Char] -> ShM ()
forall a b. (a -> b) -> a -> b
$ [Char]
"\"$HOME/.ghcup/bin/ghcup\" install ghc \"$HCVER\" || (cat \"$HOME\"/.ghcup/logs/*.* && false)"
                ShM ()
installGhcupCabal
                Bool -> ShM () -> ShM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Set [Char] -> Bool
forall a. Set a -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null Set [Char]
cfgApt) (ShM () -> ShM ()) -> ShM () -> ShM ()
forall a b. (a -> b) -> a -> b
$ do
                    [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh [Char]
"apt-get update"
                    [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh ([Char] -> ShM ()) -> [Char] -> ShM ()
forall a b. (a -> b) -> a -> b
$ [Char]
"apt-get install -y " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [[Char]] -> [Char]
unwords (Set [Char] -> [[Char]]
forall a. Set a -> [a]
S.toList Set [Char]
cfgApt)

            [Sh] -> [Sh] -> ShM ()
setup [Sh]
hvrppa [Sh]
ghcup

        [Char]
-> Map [Char] [Char]
-> ShM ()
-> ListBuilder (Either HsCiError GitHubStep) ()
githubRun' [Char]
"Set PATH and environment variables" Map [Char] [Char]
envEnv (ShM () -> ListBuilder (Either HsCiError GitHubStep) ())
-> ShM () -> ListBuilder (Either HsCiError GitHubStep) ()
forall a b. (a -> b) -> a -> b
$ do
            [Char] -> [Char] -> ShM ()
echo_to [Char]
"$GITHUB_PATH" [Char]
"$HOME/.cabal/bin"

            -- Hack: happy needs ghc. Let's install version matching GHCJS.
            -- At the moment, there is only GHCJS-8.4, so we install GHC-8.4.4
            Bool -> ShM () -> ShM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
anyGHCJS (ShM () -> ShM ()) -> ShM () -> ShM ()
forall a b. (a -> b) -> a -> b
$
                CompilerRange -> [Char] -> [Char] -> ShM ()
echo_if_to CompilerRange
RangeGHCJS [Char]
"$GITHUB_PATH" [Char]
"/opt/ghc/8.4.4/bin"

            [Char] -> [Char] -> ShM ()
tell_env [Char]
"LANG" [Char]
"C.UTF-8"

            [Char] -> [Char] -> ShM ()
tell_env [Char]
"CABAL_DIR"    [Char]
"$HOME/.cabal"
            [Char] -> [Char] -> ShM ()
tell_env [Char]
"CABAL_CONFIG" [Char]
"$HOME/.cabal/config"

            [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh [Char]
"HCDIR=/opt/$HCKIND/$HCVER"

            let ghcupCabalPath :: ShM ()
ghcupCabalPath = [Char] -> [Char] -> ShM ()
tell_env [Char]
"CABAL" ([Char] -> ShM ()) -> [Char] -> ShM ()
forall a b. (a -> b) -> a -> b
$ [Char]
"$HOME/.ghcup/bin/cabal-" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
cabalFullVer [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" -vnormal+nowrap"

            [Sh]
hvrppa <- ShM () -> ShM [Sh]
forall e (m :: * -> *).
(MonadErr e m, FromHsCiError e) =>
ShM () -> m [Sh]
runSh (ShM () -> ShM [Sh]) -> ShM () -> ShM [Sh]
forall a b. (a -> b) -> a -> b
$ do
                let hc :: [Char]
hc = [Char]
"$HCDIR/bin/$HCKIND"
                [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh ([Char] -> ShM ()) -> [Char] -> ShM ()
forall a b. (a -> b) -> a -> b
$ [Char]
"HC=" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
hc -- HC is an absolute path.
                [Char] -> [Char] -> ShM ()
tell_env [Char]
"HC" [Char]
"$HC"
                [Char] -> [Char] -> ShM ()
tell_env [Char]
"HCPKG" ([Char] -> ShM ()) -> [Char] -> ShM ()
forall a b. (a -> b) -> a -> b
$ [Char]
hc [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"-pkg"
                [Char] -> [Char] -> ShM ()
tell_env [Char]
"HADDOCK" [Char]
"$HCDIR/bin/haddock"
                if Bool
cfgGhcupCabal
                then ShM ()
ghcupCabalPath
                else [Char] -> [Char] -> ShM ()
tell_env [Char]
"CABAL" ([Char] -> ShM ()) -> [Char] -> ShM ()
forall a b. (a -> b) -> a -> b
$ [Char]
"/opt/cabal/" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
cabalVer [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"/bin/cabal -vnormal+nowrap"

            [Sh]
ghcup <- ShM () -> ShM [Sh]
forall e (m :: * -> *).
(MonadErr e m, FromHsCiError e) =>
ShM () -> m [Sh]
runSh (ShM () -> ShM [Sh]) -> ShM () -> ShM [Sh]
forall a b. (a -> b) -> a -> b
$ do
                [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh ([Char] -> ShM ()) -> [Char] -> ShM ()
forall a b. (a -> b) -> a -> b
$ [Char]
"HC=$(\"$HOME/.ghcup/bin/ghcup\" whereis ghc \"$HCVER\")"
                [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh ([Char] -> ShM ()) -> [Char] -> ShM ()
forall a b. (a -> b) -> a -> b
$ [Char]
"HCPKG=$(echo \"$HC\" | sed 's#ghc$#ghc-pkg#')"
                [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh ([Char] -> ShM ()) -> [Char] -> ShM ()
forall a b. (a -> b) -> a -> b
$ [Char]
"HADDOCK=$(echo \"$HC\" | sed 's#ghc$#haddock#')"
                [Char] -> [Char] -> ShM ()
tell_env [Char]
"HC" [Char]
"$HC"
                [Char] -> [Char] -> ShM ()
tell_env [Char]
"HCPKG" [Char]
"$HCPKG"
                [Char] -> [Char] -> ShM ()
tell_env [Char]
"HADDOCK" [Char]
"$HADDOCK"
                ShM ()
ghcupCabalPath

            [Sh] -> [Sh] -> ShM ()
setup [Sh]
hvrppa [Sh]
ghcup

            [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh [Char]
"HCNUMVER=$(${HC} --numeric-version|perl -ne '/^(\\d+)\\.(\\d+)\\.(\\d+)(\\.(\\d+))?$/; print(10000 * $1 + 100 * $2 + ($3 == 0 ? $5 != 1 : $3))')"
            [Char] -> [Char] -> ShM ()
tell_env [Char]
"HCNUMVER" [Char]
"$HCNUMVER"

            CompilerRange -> [Char] -> [Char] -> ShM ()
if_then_else (VersionRange -> CompilerRange
Range VersionRange
cfgTests)
                ([Char] -> [Char] -> [Char]
tell_env' [Char]
"ARG_TESTS" [Char]
"--enable-tests")
                ([Char] -> [Char] -> [Char]
tell_env' [Char]
"ARG_TESTS" [Char]
"--disable-tests")
            CompilerRange -> [Char] -> [Char] -> ShM ()
if_then_else (VersionRange -> CompilerRange
Range VersionRange
cfgBenchmarks)
                ([Char] -> [Char] -> [Char]
tell_env' [Char]
"ARG_BENCH" [Char]
"--enable-benchmarks")
                ([Char] -> [Char] -> [Char]
tell_env' [Char]
"ARG_BENCH" [Char]
"--disable-benchmarks")
            CompilerRange -> [Char] -> [Char] -> ShM ()
if_then_else (VersionRange -> CompilerRange
Range VersionRange
cfgHeadHackage CompilerRange -> CompilerRange -> CompilerRange
forall a. Lattice a => a -> a -> a
\/ Set CompilerVersion -> CompilerRange
RangePoints (CompilerVersion -> Set CompilerVersion
forall a. a -> Set a
S.singleton CompilerVersion
GHCHead))
                ([Char] -> [Char] -> [Char]
tell_env' [Char]
"HEADHACKAGE" [Char]
"true")
                ([Char] -> [Char] -> [Char]
tell_env' [Char]
"HEADHACKAGE" [Char]
"false")

            [Char] -> [Char] -> ShM ()
tell_env [Char]
"ARG_COMPILER" [Char]
"--$HCKIND --with-compiler=$HC"

            Bool -> ShM () -> ShM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
anyGHCJS (ShM () -> ShM ()) -> ShM () -> ShM ()
forall a b. (a -> b) -> a -> b
$
                [Char] -> [Char] -> ShM ()
tell_env [Char]
"GHCJSARITH" [Char]
"0"

        [Char] -> ShM () -> ListBuilder (Either HsCiError GitHubStep) ()
githubRun [Char]
"env" (ShM () -> ListBuilder (Either HsCiError GitHubStep) ())
-> ShM () -> ListBuilder (Either HsCiError GitHubStep) ()
forall a b. (a -> b) -> a -> b
$ do
            [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh [Char]
"env"

        [Char] -> ShM () -> ListBuilder (Either HsCiError GitHubStep) ()
githubRun [Char]
"write cabal config" (ShM () -> ListBuilder (Either HsCiError GitHubStep) ())
-> ShM () -> ListBuilder (Either HsCiError GitHubStep) ()
forall a b. (a -> b) -> a -> b
$ do
            [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh [Char]
"mkdir -p $CABAL_DIR"
            [Char] -> [Char] -> ShM ()
cat [Char]
"$CABAL_CONFIG" ([Char] -> ShM ()) -> [Char] -> ShM ()
forall a b. (a -> b) -> a -> b
$ [[Char]] -> [Char]
unlines
                [ [Char]
"remote-build-reporting: anonymous"
                , [Char]
"write-ghc-environment-files: never"
                , [Char]
"remote-repo-cache: $CABAL_DIR/packages"
                , [Char]
"logs-dir:          $CABAL_DIR/logs"
                , [Char]
"world-file:        $CABAL_DIR/world"
                , [Char]
"extra-prog-path:   $CABAL_DIR/bin"
                , [Char]
"symlink-bindir:    $CABAL_DIR/bin"
                , [Char]
"installdir:        $CABAL_DIR/bin"
                , [Char]
"build-summary:     $CABAL_DIR/logs/build.log"
                , [Char]
"store-dir:         $CABAL_DIR/store"
                , [Char]
"install-dirs user"
                , [Char]
"  prefix: $CABAL_DIR"
                , [Char]
"repository hackage.haskell.org"
                , [Char]
"  url: http://hackage.haskell.org/"
                ]

            -- Add head.hackage repository to ~/.cabal/config
            -- (locally you want to add it to cabal.project)
            Bool -> ShM () -> ShM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
anyJobUsesHeadHackage (ShM () -> ShM ()) -> ShM () -> ShM ()
forall a b. (a -> b) -> a -> b
$ [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh ([Char] -> ShM ()) -> [Char] -> ShM ()
forall a b. (a -> b) -> a -> b
$ [[Char]] -> [Char]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[Char]] -> [Char]) -> [[Char]] -> [Char]
forall a b. (a -> b) -> a -> b
$
                [ [Char]
"if $HEADHACKAGE; then\n"
                , [Char] -> [Char] -> [Char]
catCmd [Char]
"$CABAL_CONFIG" ([Char] -> [Char]) -> [Char] -> [Char]
forall a b. (a -> b) -> a -> b
$ [[Char]] -> [Char]
unlines ([[Char]] -> [Char]) -> [[Char]] -> [Char]
forall a b. (a -> b) -> a -> b
$ Bool -> [[Char]]
headHackageRepoStanza Bool
cfgHeadHackageOverride
                , [Char]
"\nfi"
                ]

            -- Cabal jobs
            Maybe Int -> (Int -> ShM ()) -> ShM ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ (Maybe Jobs
cfgJobs Maybe Jobs -> (Jobs -> Maybe Int) -> Maybe Int
forall a b. Maybe a -> (a -> Maybe b) -> Maybe b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Jobs -> Maybe Int
cabalJobs) ((Int -> ShM ()) -> ShM ()) -> (Int -> ShM ()) -> ShM ()
forall a b. (a -> b) -> a -> b
$ \Int
n ->
                [Char] -> [Char] -> ShM ()
cat [Char]
"$CABAL_CONFIG" ([Char] -> ShM ()) -> [Char] -> ShM ()
forall a b. (a -> b) -> a -> b
$ [[Char]] -> [Char]
unlines
                    [ [Char]
"jobs: " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Int -> [Char]
forall a. Show a => a -> [Char]
show Int
n
                    ]

            -- GHC jobs + ghc-options
            Maybe Int -> (Int -> ShM ()) -> ShM ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ (Maybe Jobs
cfgJobs Maybe Jobs -> (Jobs -> Maybe Int) -> Maybe Int
forall a b. Maybe a -> (a -> Maybe b) -> Maybe b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Jobs -> Maybe Int
ghcJobs) ((Int -> ShM ()) -> ShM ()) -> (Int -> ShM ()) -> ShM ()
forall a b. (a -> b) -> a -> b
$ \Int
m -> do
                CompilerRange -> [Char] -> ShM ()
sh_if (VersionRange -> CompilerRange
Range (VersionRange -> CompilerRange) -> VersionRange -> CompilerRange
forall a b. (a -> b) -> a -> b
$ Version -> VersionRange
C.orLaterVersion ([Int] -> Version
C.mkVersion [Int
7,Int
8])) ([Char] -> ShM ()) -> [Char] -> ShM ()
forall a b. (a -> b) -> a -> b
$ [Char]
"GHCJOBS=-j" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Int -> [Char]
forall a. Show a => a -> [Char]
show Int
m

            [Char] -> [Char] -> ShM ()
cat [Char]
"$CABAL_CONFIG" ([Char] -> ShM ()) -> [Char] -> ShM ()
forall a b. (a -> b) -> a -> b
$ [[Char]] -> [Char]
unlines
                [ [Char]
"program-default-options"
                , [Char]
"  ghc-options: $GHCJOBS +RTS -M3G -RTS"
                ]

            [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh [Char]
"cat $CABAL_CONFIG"

        [Char] -> ShM () -> ListBuilder (Either HsCiError GitHubStep) ()
githubRun [Char]
"versions" (ShM () -> ListBuilder (Either HsCiError GitHubStep) ())
-> ShM () -> ListBuilder (Either HsCiError GitHubStep) ()
forall a b. (a -> b) -> a -> b
$ do
            [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh [Char]
"$HC --version || true"
            [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh [Char]
"$HC --print-project-git-commit-id || true"
            [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh [Char]
"$CABAL --version || true"
            Bool -> ShM () -> ShM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
anyGHCJS (ShM () -> ShM ()) -> ShM () -> ShM ()
forall a b. (a -> b) -> a -> b
$ do
                CompilerRange -> [Char] -> ShM ()
sh_if CompilerRange
RangeGHCJS [Char]
"node --version"
                CompilerRange -> [Char] -> ShM ()
sh_if CompilerRange
RangeGHCJS [Char]
"echo $GHCJS"

        [Char] -> ShM () -> ListBuilder (Either HsCiError GitHubStep) ()
githubRun [Char]
"update cabal index" (ShM () -> ListBuilder (Either HsCiError GitHubStep) ())
-> ShM () -> ListBuilder (Either HsCiError GitHubStep) ()
forall a b. (a -> b) -> a -> b
$ do
            [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh [Char]
"$CABAL v2-update -v"

        let toolsConfigHash :: String
            toolsConfigHash :: [Char]
toolsConfigHash = Int -> [Char] -> [Char]
forall a. Int -> [a] -> [a]
take Int
8 ([Char] -> [Char]) -> [Char] -> [Char]
forall a b. (a -> b) -> a -> b
$ ByteString -> [Char]
BS8.unpack (ByteString -> [Char]) -> ByteString -> [Char]
forall a b. (a -> b) -> a -> b
$ ByteString -> ByteString
Base16.encode (ByteString -> ByteString) -> ByteString -> ByteString
forall a b. (a -> b) -> a -> b
$ ByteString -> ByteString
SHA256.hashlazy (ByteString -> ByteString) -> ByteString -> ByteString
forall a b. (a -> b) -> a -> b
$ Put -> ByteString
Binary.runPut (Put -> ByteString) -> Put -> ByteString
forall a b. (a -> b) -> a -> b
$ do
                DoctestConfig -> Put
forall t. Binary t => t -> Put
Binary.put DoctestConfig
cfgDoctest
                HLintConfig -> Put
forall t. Binary t => t -> Put
Binary.put HLintConfig
cfgHLint
                VersionRange -> Put
forall t. Binary t => t -> Put
Binary.put VersionRange
cfgGhcupJobs -- GHC location affects doctest, e.g

        Bool
-> ListBuilder (Either HsCiError GitHubStep) ()
-> ListBuilder (Either HsCiError GitHubStep) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Bool
doctestEnabled Bool -> Bool -> Bool
|| HLintConfig -> Bool
cfgHLintEnabled HLintConfig
cfgHLint) (ListBuilder (Either HsCiError GitHubStep) ()
 -> ListBuilder (Either HsCiError GitHubStep) ())
-> ListBuilder (Either HsCiError GitHubStep) ()
-> ListBuilder (Either HsCiError GitHubStep) ()
forall a b. (a -> b) -> a -> b
$ [Char]
-> [Char]
-> [([Char], [Char])]
-> ListBuilder (Either HsCiError GitHubStep) ()
githubUses [Char]
"cache (tools)" [Char]
"actions/cache/restore@v3"
            [ ([Char]
"key", [Char]
"${{ runner.os }}-${{ matrix.compiler }}-tools-" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
toolsConfigHash)
            , ([Char]
"path", [Char]
"~/.haskell-ci-tools")
            ]

        [Char] -> ShM () -> ListBuilder (Either HsCiError GitHubStep) ()
githubRun [Char]
"install cabal-plan" (ShM () -> ListBuilder (Either HsCiError GitHubStep) ())
-> ShM () -> ListBuilder (Either HsCiError GitHubStep) ()
forall a b. (a -> b) -> a -> b
$ do
            [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh [Char]
"mkdir -p $HOME/.cabal/bin"
            [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh [Char]
"curl -sL https://github.com/haskell-hvr/cabal-plan/releases/download/v0.7.3.0/cabal-plan-0.7.3.0-x86_64-linux.xz > cabal-plan.xz"
            [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh [Char]
"echo 'f62ccb2971567a5f638f2005ad3173dba14693a45154c1508645c52289714cb2  cabal-plan.xz' | sha256sum -c -"
            [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh [Char]
"xz -d < cabal-plan.xz > $HOME/.cabal/bin/cabal-plan"
            [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh [Char]
"rm -f cabal-plan.xz"
            [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh [Char]
"chmod a+x $HOME/.cabal/bin/cabal-plan"
            [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh [Char]
"cabal-plan --version"

        Bool
-> ListBuilder (Either HsCiError GitHubStep) ()
-> ListBuilder (Either HsCiError GitHubStep) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
anyGHCJS (ListBuilder (Either HsCiError GitHubStep) ()
 -> ListBuilder (Either HsCiError GitHubStep) ())
-> ListBuilder (Either HsCiError GitHubStep) ()
-> ListBuilder (Either HsCiError GitHubStep) ()
forall a b. (a -> b) -> a -> b
$ [Char] -> ShM () -> ListBuilder (Either HsCiError GitHubStep) ()
githubRun [Char]
"install happy" (ShM () -> ListBuilder (Either HsCiError GitHubStep) ())
-> ShM () -> ListBuilder (Either HsCiError GitHubStep) ()
forall a b. (a -> b) -> a -> b
$ do
            [PackageName] -> (PackageName -> ShM ()) -> ShM ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ [PackageName]
cfgGhcjsTools ((PackageName -> ShM ()) -> ShM ())
-> (PackageName -> ShM ()) -> ShM ()
forall a b. (a -> b) -> a -> b
$ \PackageName
t ->
                CompilerRange -> [Char] -> ShM ()
sh_if CompilerRange
RangeGHCJS ([Char] -> ShM ()) -> [Char] -> ShM ()
forall a b. (a -> b) -> a -> b
$ [Char]
"$CABAL v2-install -w ghc-8.4.4 --ignore-project -j2" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ PackageName -> [Char]
forall a. Pretty a => a -> [Char]
C.prettyShow PackageName
t

        Bool
-> ListBuilder (Either HsCiError GitHubStep) ()
-> ListBuilder (Either HsCiError GitHubStep) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
docspecEnabled (ListBuilder (Either HsCiError GitHubStep) ()
 -> ListBuilder (Either HsCiError GitHubStep) ())
-> ListBuilder (Either HsCiError GitHubStep) ()
-> ListBuilder (Either HsCiError GitHubStep) ()
forall a b. (a -> b) -> a -> b
$ [Char] -> ShM () -> ListBuilder (Either HsCiError GitHubStep) ()
githubRun [Char]
"install cabal-docspec" (ShM () -> ListBuilder (Either HsCiError GitHubStep) ())
-> ShM () -> ListBuilder (Either HsCiError GitHubStep) ()
forall a b. (a -> b) -> a -> b
$ do
            let hash :: [Char]
hash = DocspecConfig -> [Char]
cfgDocspecHash DocspecConfig
cfgDocspec
                url :: [Char]
url  = DocspecConfig -> [Char]
cfgDocspecUrl DocspecConfig
cfgDocspec
            [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh [Char]
"mkdir -p $HOME/.cabal/bin"
            [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh ([Char] -> ShM ()) -> [Char] -> ShM ()
forall a b. (a -> b) -> a -> b
$ [Char]
"curl -sL " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
url [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" > cabal-docspec.xz"
            [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh ([Char] -> ShM ()) -> [Char] -> ShM ()
forall a b. (a -> b) -> a -> b
$ [Char]
"echo '" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
hash [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"  cabal-docspec.xz' | sha256sum -c -"
            [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh [Char]
"xz -d < cabal-docspec.xz > $HOME/.cabal/bin/cabal-docspec"
            [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh [Char]
"rm -f cabal-docspec.xz"
            [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh [Char]
"chmod a+x $HOME/.cabal/bin/cabal-docspec"
            [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh [Char]
"cabal-docspec --version"

        Bool
-> ListBuilder (Either HsCiError GitHubStep) ()
-> ListBuilder (Either HsCiError GitHubStep) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
doctestEnabled (ListBuilder (Either HsCiError GitHubStep) ()
 -> ListBuilder (Either HsCiError GitHubStep) ())
-> ListBuilder (Either HsCiError GitHubStep) ()
-> ListBuilder (Either HsCiError GitHubStep) ()
forall a b. (a -> b) -> a -> b
$ [Char] -> ShM () -> ListBuilder (Either HsCiError GitHubStep) ()
githubRun [Char]
"install doctest" (ShM () -> ListBuilder (Either HsCiError GitHubStep) ())
-> ShM () -> ListBuilder (Either HsCiError GitHubStep) ()
forall a b. (a -> b) -> a -> b
$ do
            let range :: CompilerRange
range = VersionRange -> CompilerRange
Range (DoctestConfig -> VersionRange
cfgDoctestEnabled DoctestConfig
cfgDoctest) CompilerRange -> CompilerRange -> CompilerRange
forall a. Lattice a => a -> a -> a
/\ CompilerRange
doctestJobVersionRange
            CompilerRange -> [Char] -> ShM ()
sh_if CompilerRange
range [Char]
"$CABAL --store-dir=$HOME/.haskell-ci-tools/store v2-install $ARG_COMPILER --ignore-project -j2 doctest --constraint='doctest ^>=0.20'"
            CompilerRange -> [Char] -> ShM ()
sh_if CompilerRange
range [Char]
"doctest --version"

        let hlintVersionConstraint :: [Char]
hlintVersionConstraint
                | VersionRange -> Bool
C.isAnyVersion (HLintConfig -> VersionRange
cfgHLintVersion HLintConfig
cfgHLint) = [Char]
""
                | Bool
otherwise = [Char]
" --constraint='hlint " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ VersionRange -> [Char]
forall a. Pretty a => a -> [Char]
prettyShow (HLintConfig -> VersionRange
cfgHLintVersion HLintConfig
cfgHLint) [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"'"
        Bool
-> ListBuilder (Either HsCiError GitHubStep) ()
-> ListBuilder (Either HsCiError GitHubStep) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (HLintConfig -> Bool
cfgHLintEnabled HLintConfig
cfgHLint) (ListBuilder (Either HsCiError GitHubStep) ()
 -> ListBuilder (Either HsCiError GitHubStep) ())
-> ListBuilder (Either HsCiError GitHubStep) ()
-> ListBuilder (Either HsCiError GitHubStep) ()
forall a b. (a -> b) -> a -> b
$ [Char] -> ShM () -> ListBuilder (Either HsCiError GitHubStep) ()
githubRun [Char]
"install hlint" (ShM () -> ListBuilder (Either HsCiError GitHubStep) ())
-> ShM () -> ListBuilder (Either HsCiError GitHubStep) ()
forall a b. (a -> b) -> a -> b
$ do
            let forHLint :: [Char] -> ShM ()
forHLint = CompilerRange -> [Char] -> ShM ()
sh_if (Set CompilerVersion -> VersionRange -> HLintJob -> CompilerRange
hlintJobVersionRange Set CompilerVersion
allVersions VersionRange
cfgHeadHackage (HLintConfig -> HLintJob
cfgHLintJob HLintConfig
cfgHLint))
            if HLintConfig -> Bool
cfgHLintDownload HLintConfig
cfgHLint
            then do
                -- install --dry-run and use perl regex magic to find a hlint version
                -- -v is important
                [Char] -> ShM ()
forHLint ([Char] -> ShM ()) -> [Char] -> ShM ()
forall a b. (a -> b) -> a -> b
$ [Char]
"HLINTVER=$(cd /tmp && (${CABAL} v2-install -v $ARG_COMPILER --dry-run hlint " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
hlintVersionConstraint [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" |  perl -ne 'if (/\\bhlint-(\\d+(\\.\\d+)*)\\b/) { print \"$1\"; last; }')); echo \"HLint version $HLINTVER\""
                [Char] -> ShM ()
forHLint ([Char] -> ShM ()) -> [Char] -> ShM ()
forall a b. (a -> b) -> a -> b
$ [Char]
"if [ ! -e $HOME/.haskell-ci-tools/hlint-$HLINTVER/hlint ]; then " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [[Char]] -> [Char]
unwords
                    [ [Char]
"echo \"Downloading HLint version $HLINTVER\";"
                    , [Char]
"mkdir -p $HOME/.haskell-ci-tools;"
                    , [Char]
"curl --write-out 'Status Code: %{http_code} Redirects: %{num_redirects} Total time: %{time_total} Total Dsize: %{size_download}\\n' --silent --location --output $HOME/.haskell-ci-tools/hlint-$HLINTVER.tar.gz \"https://github.com/ndmitchell/hlint/releases/download/v$HLINTVER/hlint-$HLINTVER-x86_64-linux.tar.gz\";"
                    , [Char]
"tar -xzv -f $HOME/.haskell-ci-tools/hlint-$HLINTVER.tar.gz -C $HOME/.haskell-ci-tools;"
                    , [Char]
"fi"
                    ]
                [Char] -> ShM ()
forHLint [Char]
"mkdir -p $CABAL_DIR/bin && ln -sf \"$HOME/.haskell-ci-tools/hlint-$HLINTVER/hlint\" $CABAL_DIR/bin/hlint"
                [Char] -> ShM ()
forHLint [Char]
"hlint --version"

            else do
                [Char] -> ShM ()
forHLint ([Char] -> ShM ()) -> [Char] -> ShM ()
forall a b. (a -> b) -> a -> b
$ [Char]
"$CABAL --store-dir=$HOME/.haskell-ci-tools/store v2-install $ARG_COMPILER --ignore-project -j2 hlint" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
hlintVersionConstraint
                [Char] -> ShM ()
forHLint [Char]
"hlint --version"

        Bool
-> ListBuilder (Either HsCiError GitHubStep) ()
-> ListBuilder (Either HsCiError GitHubStep) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Bool
doctestEnabled Bool -> Bool -> Bool
|| HLintConfig -> Bool
cfgHLintEnabled HLintConfig
cfgHLint) (ListBuilder (Either HsCiError GitHubStep) ()
 -> ListBuilder (Either HsCiError GitHubStep) ())
-> ListBuilder (Either HsCiError GitHubStep) ()
-> ListBuilder (Either HsCiError GitHubStep) ()
forall a b. (a -> b) -> a -> b
$ [Char]
-> [Char]
-> [Char]
-> [([Char], [Char])]
-> ListBuilder (Either HsCiError GitHubStep) ()
githubUsesIf [Char]
"save cache (tools)" [Char]
"actions/cache/save@v3" [Char]
"always()"
            [ ([Char]
"key", [Char]
"${{ runner.os }}-${{ matrix.compiler }}-tools-" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
toolsConfigHash)
            , ([Char]
"path", [Char]
"~/.haskell-ci-tools")
            ]

        [Char]
-> [Char]
-> [([Char], [Char])]
-> ListBuilder (Either HsCiError GitHubStep) ()
githubUses [Char]
"checkout" [Char]
"actions/checkout@v3" ([([Char], [Char])]
 -> ListBuilder (Either HsCiError GitHubStep) ())
-> [([Char], [Char])]
-> ListBuilder (Either HsCiError GitHubStep) ()
forall a b. (a -> b) -> a -> b
$ ListBuilder ([Char], [Char]) () -> [([Char], [Char])]
forall x. ListBuilder x () -> [x]
buildList (ListBuilder ([Char], [Char]) () -> [([Char], [Char])])
-> ListBuilder ([Char], [Char]) () -> [([Char], [Char])]
forall a b. (a -> b) -> a -> b
$ do
            ([Char], [Char]) -> ListBuilder ([Char], [Char]) ()
forall x. x -> ListBuilder x ()
item ([Char]
"path", [Char]
"source")
            Bool
-> ListBuilder ([Char], [Char]) ()
-> ListBuilder ([Char], [Char]) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
cfgSubmodules (ListBuilder ([Char], [Char]) ()
 -> ListBuilder ([Char], [Char]) ())
-> ListBuilder ([Char], [Char]) ()
-> ListBuilder ([Char], [Char]) ()
forall a b. (a -> b) -> a -> b
$
                ([Char], [Char]) -> ListBuilder ([Char], [Char]) ()
forall x. x -> ListBuilder x ()
item ([Char]
"submodules", [Char]
"true")

        [Char] -> ShM () -> ListBuilder (Either HsCiError GitHubStep) ()
githubRun [Char]
"initial cabal.project for sdist" (ShM () -> ListBuilder (Either HsCiError GitHubStep) ())
-> ShM () -> ListBuilder (Either HsCiError GitHubStep) ()
forall a b. (a -> b) -> a -> b
$ do
            [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh [Char]
"touch cabal.project"
            [Package] -> (Package -> ShM ()) -> ShM ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ [Package]
pkgs ((Package -> ShM ()) -> ShM ()) -> (Package -> ShM ()) -> ShM ()
forall a b. (a -> b) -> a -> b
$ \Package
pkg ->
                CompilerRange -> [Char] -> [Char] -> ShM ()
echo_if_to (Set CompilerVersion -> CompilerRange
RangePoints (Set CompilerVersion -> CompilerRange)
-> Set CompilerVersion -> CompilerRange
forall a b. (a -> b) -> a -> b
$ Package -> Set CompilerVersion
pkgJobs Package
pkg) [Char]
"cabal.project" ([Char] -> ShM ()) -> [Char] -> ShM ()
forall a b. (a -> b) -> a -> b
$ [Char]
"packages: $GITHUB_WORKSPACE/source/" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Package -> [Char]
pkgDir Package
pkg
            [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh [Char]
"cat cabal.project"

        [Char] -> ShM () -> ListBuilder (Either HsCiError GitHubStep) ()
githubRun [Char]
"sdist" (ShM () -> ListBuilder (Either HsCiError GitHubStep) ())
-> ShM () -> ListBuilder (Either HsCiError GitHubStep) ()
forall a b. (a -> b) -> a -> b
$ do
            [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh [Char]
"mkdir -p sdist"
            [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh [Char]
"$CABAL sdist all --output-dir $GITHUB_WORKSPACE/sdist"

        [Char] -> ShM () -> ListBuilder (Either HsCiError GitHubStep) ()
githubRun [Char]
"unpack" (ShM () -> ListBuilder (Either HsCiError GitHubStep) ())
-> ShM () -> ListBuilder (Either HsCiError GitHubStep) ()
forall a b. (a -> b) -> a -> b
$ do
            [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh [Char]
"mkdir -p unpacked"
            [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh [Char]
"find sdist -maxdepth 1 -type f -name '*.tar.gz' -exec tar -C $GITHUB_WORKSPACE/unpacked -xzvf {} \\;"

        [Char] -> ShM () -> ListBuilder (Either HsCiError GitHubStep) ()
githubRun [Char]
"generate cabal.project" (ShM () -> ListBuilder (Either HsCiError GitHubStep) ())
-> ShM () -> ListBuilder (Either HsCiError GitHubStep) ()
forall a b. (a -> b) -> a -> b
$ do
            [Package] -> (Package -> ShM ()) -> ShM ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ [Package]
pkgs ((Package -> ShM ()) -> ShM ()) -> (Package -> ShM ()) -> ShM ()
forall a b. (a -> b) -> a -> b
$ \Pkg{[Char]
pkgName :: [Char]
pkgName :: Package -> [Char]
pkgName} -> do
                [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh ([Char] -> ShM ()) -> [Char] -> ShM ()
forall a b. (a -> b) -> a -> b
$ [Char] -> [Char]
pkgNameDirVariable' [Char]
pkgName [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"=\"$(find \"$GITHUB_WORKSPACE/unpacked\" -maxdepth 1 -type d -regex '.*/" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
pkgName [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"-[0-9.]*')\""
                [Char] -> [Char] -> ShM ()
tell_env ([Char] -> [Char]
pkgNameDirVariable' [Char]
pkgName) ([Char] -> [Char]
pkgNameDirVariable [Char]
pkgName)

            [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh [Char]
"rm -f cabal.project cabal.project.local"
            [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh [Char]
"touch cabal.project"
            [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh [Char]
"touch cabal.project.local"

            [Package] -> (Package -> ShM ()) -> ShM ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ [Package]
pkgs ((Package -> ShM ()) -> ShM ()) -> (Package -> ShM ()) -> ShM ()
forall a b. (a -> b) -> a -> b
$ \Package
pkg ->
                CompilerRange -> [Char] -> [Char] -> ShM ()
echo_if_to (Set CompilerVersion -> CompilerRange
RangePoints (Set CompilerVersion -> CompilerRange)
-> Set CompilerVersion -> CompilerRange
forall a b. (a -> b) -> a -> b
$ Package -> Set CompilerVersion
pkgJobs Package
pkg) [Char]
"cabal.project" ([Char] -> ShM ()) -> [Char] -> ShM ()
forall a b. (a -> b) -> a -> b
$ [Char]
"packages: " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char] -> [Char]
pkgNameDirVariable (Package -> [Char]
pkgName Package
pkg)

            -- per package options
            case PackageScope
cfgErrorMissingMethods of
                PackageScope
PackageScopeNone  -> () -> ShM ()
forall a. a -> ShM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
                PackageScope
PackageScopeLocal -> [Package] -> (Package -> ShM ()) -> ShM ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ [Package]
pkgs ((Package -> ShM ()) -> ShM ()) -> (Package -> ShM ()) -> ShM ()
forall a b. (a -> b) -> a -> b
$ \Pkg{[Char]
pkgName :: Package -> [Char]
pkgName :: [Char]
pkgName,Set CompilerVersion
pkgJobs :: Package -> Set CompilerVersion
pkgJobs :: Set CompilerVersion
pkgJobs} -> do
                    let range :: CompilerRange
range = VersionRange -> CompilerRange
Range (Version -> VersionRange
C.orLaterVersion ([Int] -> Version
C.mkVersion [Int
8,Int
2])) CompilerRange -> CompilerRange -> CompilerRange
forall a. Lattice a => a -> a -> a
/\ Set CompilerVersion -> CompilerRange
RangePoints Set CompilerVersion
pkgJobs
                    CompilerRange -> [Char] -> [Char] -> ShM ()
echo_if_to CompilerRange
range [Char]
"cabal.project" ([Char] -> ShM ()) -> [Char] -> ShM ()
forall a b. (a -> b) -> a -> b
$ [Char]
"package " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
pkgName
                    CompilerRange -> [Char] -> [Char] -> ShM ()
echo_if_to CompilerRange
range [Char]
"cabal.project" ([Char] -> ShM ()) -> [Char] -> ShM ()
forall a b. (a -> b) -> a -> b
$ [Char]
"    ghc-options: -Werror=missing-methods"
                PackageScope
PackageScopeAll   -> [Char] -> [Char] -> ShM ()
cat [Char]
"cabal.project" ([Char] -> ShM ()) -> [Char] -> ShM ()
forall a b. (a -> b) -> a -> b
$ [[Char]] -> [Char]
unlines
                    [ [Char]
"package *"
                    , [Char]
"  ghc-options: -Werror=missing-methods -Werror=missing-fields"
                    ]

            -- extra cabal.project fields
            [Char] -> [Char] -> ShM ()
cat [Char]
"cabal.project" ([Char] -> ShM ()) -> [Char] -> ShM ()
forall a b. (a -> b) -> a -> b
$ (() -> CommentPosition)
-> (() -> [[Char]] -> [[Char]])
-> Int
-> [PrettyField ()]
-> [Char]
forall ann.
(ann -> CommentPosition)
-> (ann -> [[Char]] -> [[Char]])
-> Int
-> [PrettyField ann]
-> [Char]
C.showFields' (CommentPosition -> () -> CommentPosition
forall a b. a -> b -> a
const CommentPosition
C.NoComment) (([[Char]] -> [[Char]]) -> () -> [[Char]] -> [[Char]]
forall a b. a -> b -> a
const [[Char]] -> [[Char]]
forall a. a -> a
id) Int
2 ([PrettyField ()] -> [Char]) -> [PrettyField ()] -> [Char]
forall a b. (a -> b) -> a -> b
$ [Char] -> [PrettyField ()]
extraCabalProjectFields [Char]
"$GITHUB_WORKSPACE/source/"

            -- If using head.hackage, allow building with newer versions of GHC boot libraries.
            -- Note that we put this in a cabal.project file, not ~/.cabal/config, in order to avoid
            -- https://github.com/haskell/cabal/issues/7291.
            Bool -> ShM () -> ShM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
anyJobUsesHeadHackage (ShM () -> ShM ()) -> ShM () -> ShM ()
forall a b. (a -> b) -> a -> b
$ [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh ([Char] -> ShM ()) -> [Char] -> ShM ()
forall a b. (a -> b) -> a -> b
$ [[Char]] -> [Char]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[Char]] -> [Char]) -> [[Char]] -> [Char]
forall a b. (a -> b) -> a -> b
$
                [ [Char]
"if $HEADHACKAGE; then\n"
                , [Char]
"echo \"allow-newer: $($HCPKG list --simple-output | sed -E 's/([a-zA-Z-]+)-[0-9.]+/*:\\1,/g')\" >> cabal.project\n"
                , [Char]
"fi"
                ]

            -- also write cabal.project.local file with
            -- @
            -- constraints: base installed
            -- constraints: array installed
            -- ...
            --
            -- omitting any local package names
            case [Installed] -> InstalledNormalised
normaliseInstalled [Installed]
cfgInstalled of
                InstalledDiff Set PackageName
pns -> [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh ([Char] -> ShM ()) -> [Char] -> ShM ()
forall a b. (a -> b) -> a -> b
$ [[Char]] -> [Char]
unwords
                    [ [Char]
"$HCPKG list --simple-output --names-only"
                    , [Char]
"| perl -ne 'for (split /\\s+/) { print \"constraints: $_ installed\\n\" unless /" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
re [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"/; }'"
                    , [Char]
">> cabal.project.local"
                    ]
                  where
                    pns' :: Set [Char]
pns' = (PackageName -> [Char]) -> Set PackageName -> Set [Char]
forall b a. Ord b => (a -> b) -> Set a -> Set b
S.map PackageName -> [Char]
C.unPackageName Set PackageName
pns Set [Char] -> Set [Char] -> Set [Char]
forall a. Ord a => Set a -> Set a -> Set a
`S.union` (Package -> Set [Char]) -> [Package] -> Set [Char]
forall m a. Monoid m => (a -> m) -> [a] -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap ([Char] -> Set [Char]
forall a. a -> Set a
S.singleton ([Char] -> Set [Char])
-> (Package -> [Char]) -> Package -> Set [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Package -> [Char]
pkgName) [Package]
pkgs
                    re :: [Char]
re = [Char]
"^(" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char] -> [[Char]] -> [Char]
forall a. [a] -> [[a]] -> [a]
intercalate [Char]
"|" (Set [Char] -> [[Char]]
forall a. Set a -> [a]
S.toList Set [Char]
pns') [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
")$"

                InstalledOnly Set PackageName
pns | Bool -> Bool
not (Set [Char] -> Bool
forall a. Set a -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null Set [Char]
pns') -> [Char] -> [Char] -> ShM ()
cat [Char]
"cabal.project.local" ([Char] -> ShM ()) -> [Char] -> ShM ()
forall a b. (a -> b) -> a -> b
$ [[Char]] -> [Char]
unlines
                    [ [Char]
"constraints: " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
pkg [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" installed"
                    | [Char]
pkg <- Set [Char] -> [[Char]]
forall a. Set a -> [a]
S.toList Set [Char]
pns'
                    ]
                  where
                    pns' :: Set [Char]
pns' = (PackageName -> [Char]) -> Set PackageName -> Set [Char]
forall b a. Ord b => (a -> b) -> Set a -> Set b
S.map PackageName -> [Char]
C.unPackageName Set PackageName
pns Set [Char] -> Set [Char] -> Set [Char]
forall a. Ord a => Set a -> Set a -> Set a
`S.difference` (Package -> Set [Char]) -> [Package] -> Set [Char]
forall m a. Monoid m => (a -> m) -> [a] -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap ([Char] -> Set [Char]
forall a. a -> Set a
S.singleton ([Char] -> Set [Char])
-> (Package -> [Char]) -> Package -> Set [Char]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Package -> [Char]
pkgName) [Package]
pkgs

                -- otherwise: nothing
                InstalledNormalised
_ -> () -> ShM ()
forall a. a -> ShM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()

            [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh [Char]
"cat cabal.project"
            [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh [Char]
"cat cabal.project.local"

        [Char] -> ShM () -> ListBuilder (Either HsCiError GitHubStep) ()
githubRun [Char]
"dump install plan" (ShM () -> ListBuilder (Either HsCiError GitHubStep) ())
-> ShM () -> ListBuilder (Either HsCiError GitHubStep) ()
forall a b. (a -> b) -> a -> b
$ do
            [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh [Char]
"$CABAL v2-build $ARG_COMPILER $ARG_TESTS $ARG_BENCH --dry-run all"
            [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh [Char]
"cabal-plan"

        -- This a hack. https://github.com/actions/cache/issues/109
        -- Hashing Java - Maven style.
        [Char]
-> [Char]
-> [([Char], [Char])]
-> ListBuilder (Either HsCiError GitHubStep) ()
githubUses [Char]
"restore cache" [Char]
"actions/cache/restore@v3"
            [ ([Char]
"key", [Char]
"${{ runner.os }}-${{ matrix.compiler }}-${{ github.sha }}")
            , ([Char]
"restore-keys", [Char]
"${{ runner.os }}-${{ matrix.compiler }}-")
            , ([Char]
"path", [Char]
"~/.cabal/store")
            ]

        -- install dependencies
        Bool
-> ListBuilder (Either HsCiError GitHubStep) ()
-> ListBuilder (Either HsCiError GitHubStep) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
cfgInstallDeps (ListBuilder (Either HsCiError GitHubStep) ()
 -> ListBuilder (Either HsCiError GitHubStep) ())
-> ListBuilder (Either HsCiError GitHubStep) ()
-> ListBuilder (Either HsCiError GitHubStep) ()
forall a b. (a -> b) -> a -> b
$ [Char] -> ShM () -> ListBuilder (Either HsCiError GitHubStep) ()
githubRun [Char]
"install dependencies" (ShM () -> ListBuilder (Either HsCiError GitHubStep) ())
-> ShM () -> ListBuilder (Either HsCiError GitHubStep) ()
forall a b. (a -> b) -> a -> b
$ do
            [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh [Char]
"$CABAL v2-build $ARG_COMPILER --disable-tests --disable-benchmarks --dependencies-only -j2 all"
            [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh [Char]
"$CABAL v2-build $ARG_COMPILER $ARG_TESTS $ARG_BENCH --dependencies-only -j2 all"

        -- build w/o tests benchs
        Bool
-> ListBuilder (Either HsCiError GitHubStep) ()
-> ListBuilder (Either HsCiError GitHubStep) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (VersionRange -> VersionRange -> Bool
equivVersionRanges VersionRange
C.noVersion VersionRange
cfgNoTestsNoBench) (ListBuilder (Either HsCiError GitHubStep) ()
 -> ListBuilder (Either HsCiError GitHubStep) ())
-> ListBuilder (Either HsCiError GitHubStep) ()
-> ListBuilder (Either HsCiError GitHubStep) ()
forall a b. (a -> b) -> a -> b
$ [Char] -> ShM () -> ListBuilder (Either HsCiError GitHubStep) ()
githubRun [Char]
"build w/o tests" (ShM () -> ListBuilder (Either HsCiError GitHubStep) ())
-> ShM () -> ListBuilder (Either HsCiError GitHubStep) ()
forall a b. (a -> b) -> a -> b
$ do
            [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh [Char]
"$CABAL v2-build $ARG_COMPILER --disable-tests --disable-benchmarks all"

        -- build
        [Char] -> ShM () -> ListBuilder (Either HsCiError GitHubStep) ()
githubRun [Char]
"build" (ShM () -> ListBuilder (Either HsCiError GitHubStep) ())
-> ShM () -> ListBuilder (Either HsCiError GitHubStep) ()
forall a b. (a -> b) -> a -> b
$ do
            [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh [Char]
"$CABAL v2-build $ARG_COMPILER $ARG_TESTS $ARG_BENCH all --write-ghc-environment-files=always"

        -- tests
        [Char] -> ShM () -> ListBuilder (Either HsCiError GitHubStep) ()
githubRun [Char]
"tests" (ShM () -> ListBuilder (Either HsCiError GitHubStep) ())
-> ShM () -> ListBuilder (Either HsCiError GitHubStep) ()
forall a b. (a -> b) -> a -> b
$ do
            let range :: CompilerRange
range = CompilerRange
RangeGHC CompilerRange -> CompilerRange -> CompilerRange
forall a. Lattice a => a -> a -> a
/\ VersionRange -> CompilerRange
Range (VersionRange
cfgTests VersionRange -> VersionRange -> VersionRange
forall a. Lattice a => a -> a -> a
/\ VersionRange
cfgRunTests) CompilerRange -> CompilerRange -> CompilerRange
forall a. Lattice a => a -> a -> a
/\ CompilerRange
hasTests
            CompilerRange -> [Char] -> ShM ()
sh_if CompilerRange
range ([Char] -> ShM ()) -> [Char] -> ShM ()
forall a b. (a -> b) -> a -> b
$ [Char]
"$CABAL v2-test $ARG_COMPILER $ARG_TESTS $ARG_BENCH all" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
testShowDetails

            Bool -> ShM () -> ShM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Bool
anyGHCJS Bool -> Bool -> Bool
&& Bool
cfgGhcjsTests) (ShM () -> ShM ()) -> ShM () -> ShM ()
forall a b. (a -> b) -> a -> b
$ [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh ([Char] -> ShM ()) -> [Char] -> ShM ()
forall a b. (a -> b) -> a -> b
$ [[Char]] -> [Char]
unlines ([[Char]] -> [Char]) -> [[Char]] -> [Char]
forall a b. (a -> b) -> a -> b
$
                [ [Char]
"pkgdir() {"
                , [Char]
"  case $1 in"
                ] [[Char]] -> [[Char]] -> [[Char]]
forall a. [a] -> [a] -> [a]
++
                [ [Char]
"    " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
pkgName [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
") echo " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char] -> [Char]
pkgNameDirVariable [Char]
pkgName [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" ;;"
                | Pkg{[Char]
pkgName :: Package -> [Char]
pkgName :: [Char]
pkgName} <- [Package]
pkgs
                ] [[Char]] -> [[Char]] -> [[Char]]
forall a. [a] -> [a] -> [a]
++
                [ [Char]
"  esac"
                , [Char]
"}"
                ]

            Bool -> ShM () -> ShM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
cfgGhcjsTests (ShM () -> ShM ()) -> ShM () -> ShM ()
forall a b. (a -> b) -> a -> b
$ CompilerRange -> [Char] -> ShM ()
sh_if (CompilerRange
RangeGHCJS CompilerRange -> CompilerRange -> CompilerRange
forall a. Lattice a => a -> a -> a
/\ CompilerRange
hasTests) ([Char] -> ShM ()) -> [Char] -> ShM ()
forall a b. (a -> b) -> a -> b
$ [[Char]] -> [Char]
unwords
                [ [Char]
"cabal-plan list-bins '*:test:*' | while read -r line; do"
                , [Char]
"testpkg=$(echo \"$line\" | perl -pe 's/:.*//');"
                , [Char]
"testexe=$(echo \"$line\" | awk '{ print $2 }');"
                , [Char]
"echo \"testing $textexe in package $textpkg\";"
                , [Char]
"(cd \"$(pkgdir $testpkg)\" && nodejs \"$testexe\".jsexe/all.js);"
                , [Char]
"done"
                ]

        -- doctest
        Bool
-> ListBuilder (Either HsCiError GitHubStep) ()
-> ListBuilder (Either HsCiError GitHubStep) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
doctestEnabled (ListBuilder (Either HsCiError GitHubStep) ()
 -> ListBuilder (Either HsCiError GitHubStep) ())
-> ListBuilder (Either HsCiError GitHubStep) ()
-> ListBuilder (Either HsCiError GitHubStep) ()
forall a b. (a -> b) -> a -> b
$ [Char] -> ShM () -> ListBuilder (Either HsCiError GitHubStep) ()
githubRun [Char]
"doctest" (ShM () -> ListBuilder (Either HsCiError GitHubStep) ())
-> ShM () -> ListBuilder (Either HsCiError GitHubStep) ()
forall a b. (a -> b) -> a -> b
$ do
            let doctestOptions :: [Char]
doctestOptions = [[Char]] -> [Char]
unwords ([[Char]] -> [Char]) -> [[Char]] -> [Char]
forall a b. (a -> b) -> a -> b
$ DoctestConfig -> [[Char]]
cfgDoctestOptions DoctestConfig
cfgDoctest

            Bool -> ShM () -> ShM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless ([PackageName] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null ([PackageName] -> Bool) -> [PackageName] -> Bool
forall a b. (a -> b) -> a -> b
$ DoctestConfig -> [PackageName]
cfgDoctestFilterEnvPkgs DoctestConfig
cfgDoctest) (ShM () -> ShM ()) -> ShM () -> ShM ()
forall a b. (a -> b) -> a -> b
$ do
                -- cabal-install mangles unit ids on the OSX,
                -- removing the vowels to make filepaths shorter
                let manglePkgNames :: String -> [String]
                    manglePkgNames :: [Char] -> [[Char]]
manglePkgNames [Char]
n
                        | Set CompilerVersion -> Bool
forall a. Set a -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null Set CompilerVersion
macosVersions = [[Char]
n]
                        | Bool
otherwise          = [[Char]
n, (Char -> Bool) -> [Char] -> [Char]
forall a. (a -> Bool) -> [a] -> [a]
filter Char -> Bool
notVowel [Char]
n]
                      where
                        notVowel :: Char -> Bool
notVowel Char
c = Char -> [Char] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
notElem Char
c ([Char]
"aeiou" :: String)
                let filterPkgs :: [Char]
filterPkgs = [Char] -> [[Char]] -> [Char]
forall a. [a] -> [[a]] -> [a]
intercalate [Char]
"|" ([[Char]] -> [Char]) -> [[Char]] -> [Char]
forall a b. (a -> b) -> a -> b
$ (PackageName -> [[Char]]) -> [PackageName] -> [[Char]]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap ([Char] -> [[Char]]
manglePkgNames ([Char] -> [[Char]])
-> (PackageName -> [Char]) -> PackageName -> [[Char]]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PackageName -> [Char]
C.unPackageName) ([PackageName] -> [[Char]]) -> [PackageName] -> [[Char]]
forall a b. (a -> b) -> a -> b
$ DoctestConfig -> [PackageName]
cfgDoctestFilterEnvPkgs DoctestConfig
cfgDoctest
                [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh ([Char] -> ShM ()) -> [Char] -> ShM ()
forall a b. (a -> b) -> a -> b
$ [Char]
"perl -i -e 'while (<ARGV>) { print unless /package-id\\s+(" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
filterPkgs [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
")-\\d+(\\.\\d+)*/; }' .ghc.environment.*"

            [Package] -> (Package -> ShM ()) -> ShM ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ [Package]
pkgs ((Package -> ShM ()) -> ShM ()) -> (Package -> ShM ()) -> ShM ()
forall a b. (a -> b) -> a -> b
$ \Pkg{[Char]
pkgName :: Package -> [Char]
pkgName :: [Char]
pkgName,GenericPackageDescription
pkgGpd :: GenericPackageDescription
pkgGpd :: Package -> GenericPackageDescription
pkgGpd,Set CompilerVersion
pkgJobs :: Package -> Set CompilerVersion
pkgJobs :: Set CompilerVersion
pkgJobs} ->
                Bool -> ShM () -> ShM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when ([Char] -> PackageName
C.mkPackageName [Char]
pkgName PackageName -> [PackageName] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`notElem` DoctestConfig -> [PackageName]
cfgDoctestFilterSrcPkgs DoctestConfig
cfgDoctest) (ShM () -> ShM ()) -> ShM () -> ShM ()
forall a b. (a -> b) -> a -> b
$ do
                    [[[Char]]] -> ([[Char]] -> ShM ()) -> ShM ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ (GenericPackageDescription -> [[[Char]]]
doctestArgs GenericPackageDescription
pkgGpd) (([[Char]] -> ShM ()) -> ShM ()) -> ([[Char]] -> ShM ()) -> ShM ()
forall a b. (a -> b) -> a -> b
$ \[[Char]]
args -> do
                        let args' :: [Char]
args' = [[Char]] -> [Char]
unwords [[Char]]
args
                        let vr :: CompilerRange
vr = VersionRange -> CompilerRange
Range (DoctestConfig -> VersionRange
cfgDoctestEnabled DoctestConfig
cfgDoctest)
                              CompilerRange -> CompilerRange -> CompilerRange
forall a. Lattice a => a -> a -> a
/\ CompilerRange
doctestJobVersionRange
                              CompilerRange -> CompilerRange -> CompilerRange
forall a. Lattice a => a -> a -> a
/\ Set CompilerVersion -> CompilerRange
RangePoints Set CompilerVersion
pkgJobs

                        Bool -> ShM () -> ShM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless ([[Char]] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [[Char]]
args) (ShM () -> ShM ()) -> ShM () -> ShM ()
forall a b. (a -> b) -> a -> b
$ do
                            CompilerRange -> [Char] -> ShM ()
change_dir_if CompilerRange
vr ([Char] -> ShM ()) -> [Char] -> ShM ()
forall a b. (a -> b) -> a -> b
$ [Char] -> [Char]
pkgNameDirVariable [Char]
pkgName
                            CompilerRange -> [Char] -> ShM ()
sh_if CompilerRange
vr ([Char] -> ShM ()) -> [Char] -> ShM ()
forall a b. (a -> b) -> a -> b
$ [Char]
"doctest " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
doctestOptions [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
args'

        -- docspec
        Bool
-> ListBuilder (Either HsCiError GitHubStep) ()
-> ListBuilder (Either HsCiError GitHubStep) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
docspecEnabled (ListBuilder (Either HsCiError GitHubStep) ()
 -> ListBuilder (Either HsCiError GitHubStep) ())
-> ListBuilder (Either HsCiError GitHubStep) ()
-> ListBuilder (Either HsCiError GitHubStep) ()
forall a b. (a -> b) -> a -> b
$ [Char] -> ShM () -> ListBuilder (Either HsCiError GitHubStep) ()
githubRun [Char]
"docspec" (ShM () -> ListBuilder (Either HsCiError GitHubStep) ())
-> ShM () -> ListBuilder (Either HsCiError GitHubStep) ()
forall a b. (a -> b) -> a -> b
$ do
            -- docspec doesn't work with non-GHC (i.e. GHCJS)
            let docspecRange' :: CompilerRange
docspecRange' = CompilerRange
docspecRange CompilerRange -> CompilerRange -> CompilerRange
forall a. Lattice a => a -> a -> a
/\ CompilerRange
RangeGHC
            -- we need to rebuild, if tests screwed something.
            CompilerRange -> [Char] -> ShM ()
sh_if CompilerRange
docspecRange' [Char]
"$CABAL v2-build $ARG_COMPILER $ARG_TESTS $ARG_BENCH all"
            CompilerRange -> [Char] -> ShM ()
sh_if CompilerRange
docspecRange' [Char]
cabalDocspec

        -- hlint
        Bool
-> ListBuilder (Either HsCiError GitHubStep) ()
-> ListBuilder (Either HsCiError GitHubStep) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (HLintConfig -> Bool
cfgHLintEnabled HLintConfig
cfgHLint) (ListBuilder (Either HsCiError GitHubStep) ()
 -> ListBuilder (Either HsCiError GitHubStep) ())
-> ListBuilder (Either HsCiError GitHubStep) ()
-> ListBuilder (Either HsCiError GitHubStep) ()
forall a b. (a -> b) -> a -> b
$ [Char] -> ShM () -> ListBuilder (Either HsCiError GitHubStep) ()
githubRun [Char]
"hlint" (ShM () -> ListBuilder (Either HsCiError GitHubStep) ())
-> ShM () -> ListBuilder (Either HsCiError GitHubStep) ()
forall a b. (a -> b) -> a -> b
$ do
            let [Char]
"" <+> :: [Char] -> [Char] -> [Char]
<+> [Char]
ys = [Char]
ys
                [Char]
xs <+> [Char]
"" = [Char]
xs
                [Char]
xs <+> [Char]
ys = [Char]
xs [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
ys

                prependSpace :: [Char] -> [Char]
prependSpace [Char]
"" = [Char]
""
                prependSpace [Char]
xs = [Char]
" " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
xs

            let hlintOptions :: [Char]
hlintOptions = [Char] -> [Char]
prependSpace ([Char] -> [Char]) -> [Char] -> [Char]
forall a b. (a -> b) -> a -> b
$ [Char] -> ([Char] -> [Char]) -> Maybe [Char] -> [Char]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [Char]
"" ([Char]
"-h ${GITHUB_WORKSPACE}/source/" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++) (HLintConfig -> Maybe [Char]
cfgHLintYaml HLintConfig
cfgHLint) [Char] -> [Char] -> [Char]
<+> [[Char]] -> [Char]
unwords (HLintConfig -> [[Char]]
cfgHLintOptions HLintConfig
cfgHLint)

            [Package] -> (Package -> ShM ()) -> ShM ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ [Package]
pkgs ((Package -> ShM ()) -> ShM ()) -> (Package -> ShM ()) -> ShM ()
forall a b. (a -> b) -> a -> b
$ \Pkg{[Char]
pkgName :: Package -> [Char]
pkgName :: [Char]
pkgName,GenericPackageDescription
pkgGpd :: Package -> GenericPackageDescription
pkgGpd :: GenericPackageDescription
pkgGpd,Set CompilerVersion
pkgJobs :: Package -> Set CompilerVersion
pkgJobs :: Set CompilerVersion
pkgJobs} -> do
                [[[Char]]] -> ([[Char]] -> ShM ()) -> ShM ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ (GenericPackageDescription -> [[[Char]]]
hlintArgs GenericPackageDescription
pkgGpd) (([[Char]] -> ShM ()) -> ShM ()) -> ([[Char]] -> ShM ()) -> ShM ()
forall a b. (a -> b) -> a -> b
$ \[[Char]]
args -> do
                    let args' :: [Char]
args' = [[Char]] -> [Char]
unwords [[Char]]
args
                    Bool -> ShM () -> ShM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless ([[Char]] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [[Char]]
args) (ShM () -> ShM ()) -> ShM () -> ShM ()
forall a b. (a -> b) -> a -> b
$
                        CompilerRange -> [Char] -> ShM ()
sh_if (Set CompilerVersion -> VersionRange -> HLintJob -> CompilerRange
hlintJobVersionRange Set CompilerVersion
allVersions VersionRange
cfgHeadHackage (HLintConfig -> HLintJob
cfgHLintJob HLintConfig
cfgHLint) CompilerRange -> CompilerRange -> CompilerRange
forall a. Lattice a => a -> a -> a
/\ Set CompilerVersion -> CompilerRange
RangePoints Set CompilerVersion
pkgJobs) ([Char] -> ShM ()) -> [Char] -> ShM ()
forall a b. (a -> b) -> a -> b
$
                        [Char]
"(cd " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char] -> [Char]
pkgNameDirVariable [Char]
pkgName [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" && hlint" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
hlintOptions [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
args' [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
")"

        -- cabal check
        Bool
-> ListBuilder (Either HsCiError GitHubStep) ()
-> ListBuilder (Either HsCiError GitHubStep) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
cfgCheck (ListBuilder (Either HsCiError GitHubStep) ()
 -> ListBuilder (Either HsCiError GitHubStep) ())
-> ListBuilder (Either HsCiError GitHubStep) ()
-> ListBuilder (Either HsCiError GitHubStep) ()
forall a b. (a -> b) -> a -> b
$ [Char] -> ShM () -> ListBuilder (Either HsCiError GitHubStep) ()
githubRun [Char]
"cabal check" (ShM () -> ListBuilder (Either HsCiError GitHubStep) ())
-> ShM () -> ListBuilder (Either HsCiError GitHubStep) ()
forall a b. (a -> b) -> a -> b
$ do
            [Package] -> (Package -> ShM ()) -> ShM ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ [Package]
pkgs ((Package -> ShM ()) -> ShM ()) -> (Package -> ShM ()) -> ShM ()
forall a b. (a -> b) -> a -> b
$ \Pkg{[Char]
pkgName :: Package -> [Char]
pkgName :: [Char]
pkgName,Set CompilerVersion
pkgJobs :: Package -> Set CompilerVersion
pkgJobs :: Set CompilerVersion
pkgJobs} -> do
                let range :: CompilerRange
range = Set CompilerVersion -> CompilerRange
RangePoints Set CompilerVersion
pkgJobs
                CompilerRange -> [Char] -> ShM ()
change_dir_if CompilerRange
range ([Char] -> ShM ()) -> [Char] -> ShM ()
forall a b. (a -> b) -> a -> b
$ [Char] -> [Char]
pkgNameDirVariable [Char]
pkgName
                CompilerRange -> [Char] -> ShM ()
sh_if CompilerRange
range [Char]
"${CABAL} -vnormal check"

        -- haddock
        Bool
-> ListBuilder (Either HsCiError GitHubStep) ()
-> ListBuilder (Either HsCiError GitHubStep) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
runHaddock (ListBuilder (Either HsCiError GitHubStep) ()
 -> ListBuilder (Either HsCiError GitHubStep) ())
-> ListBuilder (Either HsCiError GitHubStep) ()
-> ListBuilder (Either HsCiError GitHubStep) ()
forall a b. (a -> b) -> a -> b
$ [Char] -> ShM () -> ListBuilder (Either HsCiError GitHubStep) ()
githubRun [Char]
"haddock" (ShM () -> ListBuilder (Either HsCiError GitHubStep) ())
-> ShM () -> ListBuilder (Either HsCiError GitHubStep) ()
forall a b. (a -> b) -> a -> b
$ do
            let range :: CompilerRange
range = CompilerRange
RangeGHC CompilerRange -> CompilerRange -> CompilerRange
forall a. Lattice a => a -> a -> a
/\ VersionRange -> CompilerRange
Range VersionRange
cfgHaddock
            -- disable-documentation disables docs in deps: https://github.com/haskell/cabal/issues/7462
            CompilerRange -> [Char] -> ShM ()
sh_if CompilerRange
range ([Char] -> ShM ()) -> [Char] -> ShM ()
forall a b. (a -> b) -> a -> b
$ [Char]
"$CABAL v2-haddock --disable-documentation" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
haddockFlags [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" $ARG_COMPILER --with-haddock $HADDOCK $ARG_TESTS $ARG_BENCH all"

        -- unconstrained build
        Bool
-> ListBuilder (Either HsCiError GitHubStep) ()
-> ListBuilder (Either HsCiError GitHubStep) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (VersionRange -> VersionRange -> Bool
equivVersionRanges VersionRange
C.noVersion VersionRange
cfgUnconstrainted) (ListBuilder (Either HsCiError GitHubStep) ()
 -> ListBuilder (Either HsCiError GitHubStep) ())
-> ListBuilder (Either HsCiError GitHubStep) ()
-> ListBuilder (Either HsCiError GitHubStep) ()
forall a b. (a -> b) -> a -> b
$ [Char] -> ShM () -> ListBuilder (Either HsCiError GitHubStep) ()
githubRun [Char]
"unconstrained build" (ShM () -> ListBuilder (Either HsCiError GitHubStep) ())
-> ShM () -> ListBuilder (Either HsCiError GitHubStep) ()
forall a b. (a -> b) -> a -> b
$ do
            let range :: CompilerRange
range = VersionRange -> CompilerRange
Range VersionRange
cfgUnconstrainted
            CompilerRange -> [Char] -> ShM ()
sh_if CompilerRange
range [Char]
"rm -f cabal.project.local"
            CompilerRange -> [Char] -> ShM ()
sh_if CompilerRange
range [Char]
"$CABAL v2-build $ARG_COMPILER --disable-tests --disable-benchmarks all"

        -- constraint sets
        Bool
-> ListBuilder (Either HsCiError GitHubStep) ()
-> ListBuilder (Either HsCiError GitHubStep) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless ([ConstraintSet] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [ConstraintSet]
cfgConstraintSets) (ListBuilder (Either HsCiError GitHubStep) ()
 -> ListBuilder (Either HsCiError GitHubStep) ())
-> ListBuilder (Either HsCiError GitHubStep) ()
-> ListBuilder (Either HsCiError GitHubStep) ()
forall a b. (a -> b) -> a -> b
$ [Char] -> ShM () -> ListBuilder (Either HsCiError GitHubStep) ()
githubRun [Char]
"prepare for constraint sets" (ShM () -> ListBuilder (Either HsCiError GitHubStep) ())
-> ShM () -> ListBuilder (Either HsCiError GitHubStep) ()
forall a b. (a -> b) -> a -> b
$ do
            [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh [Char]
"rm -f cabal.project.local"

        [ConstraintSet]
-> (ConstraintSet -> ListBuilder (Either HsCiError GitHubStep) ())
-> ListBuilder (Either HsCiError GitHubStep) ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ [ConstraintSet]
cfgConstraintSets ((ConstraintSet -> ListBuilder (Either HsCiError GitHubStep) ())
 -> ListBuilder (Either HsCiError GitHubStep) ())
-> (ConstraintSet -> ListBuilder (Either HsCiError GitHubStep) ())
-> ListBuilder (Either HsCiError GitHubStep) ()
forall a b. (a -> b) -> a -> b
$ \ConstraintSet
cs -> [Char] -> ShM () -> ListBuilder (Either HsCiError GitHubStep) ()
githubRun ([Char]
"constraint set " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ ConstraintSet -> [Char]
csName ConstraintSet
cs) (ShM () -> ListBuilder (Either HsCiError GitHubStep) ())
-> ShM () -> ListBuilder (Either HsCiError GitHubStep) ()
forall a b. (a -> b) -> a -> b
$ do
            let range :: CompilerRange
range
                  | ConstraintSet -> Bool
csGhcjs ConstraintSet
cs  = VersionRange -> CompilerRange
Range (ConstraintSet -> VersionRange
csGhcVersions ConstraintSet
cs)
                  | Bool
otherwise   = CompilerRange
RangeGHC CompilerRange -> CompilerRange -> CompilerRange
forall a. Lattice a => a -> a -> a
/\ VersionRange -> CompilerRange
Range (ConstraintSet -> VersionRange
csGhcVersions ConstraintSet
cs)

            let sh_cs :: [Char] -> ShM ()
sh_cs           = CompilerRange -> [Char] -> ShM ()
sh_if CompilerRange
range
            let sh_cs' :: CompilerRange -> [Char] -> ShM ()
sh_cs' CompilerRange
r        = CompilerRange -> [Char] -> ShM ()
sh_if (CompilerRange
range CompilerRange -> CompilerRange -> CompilerRange
forall a. Lattice a => a -> a -> a
/\ CompilerRange
r)
            let testFlag :: [Char]
testFlag        = if ConstraintSet -> Bool
csTests ConstraintSet
cs then [Char]
"--enable-tests" else [Char]
"--disable-tests"
            let benchFlag :: [Char]
benchFlag       = if ConstraintSet -> Bool
csBenchmarks ConstraintSet
cs then [Char]
"--enable-benchmarks" else [Char]
"--disable-benchmarks"
            let constraintFlags :: [[Char]]
constraintFlags = ([Char] -> [Char]) -> [[Char]] -> [[Char]]
forall a b. (a -> b) -> [a] -> [b]
map (\[Char]
x ->  [Char]
"--constraint='" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
x [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"'") (ConstraintSet -> [[Char]]
csConstraints ConstraintSet
cs)
            let allFlags :: [Char]
allFlags        = [[Char]] -> [Char]
unwords ([Char]
testFlag [Char] -> [[Char]] -> [[Char]]
forall a. a -> [a] -> [a]
: [Char]
benchFlag [Char] -> [[Char]] -> [[Char]]
forall a. a -> [a] -> [a]
: [[Char]]
constraintFlags)

            [Char] -> ShM ()
sh_cs ([Char] -> ShM ()) -> [Char] -> ShM ()
forall a b. (a -> b) -> a -> b
$ [Char]
"$CABAL v2-build $ARG_COMPILER " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
allFlags [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" all --dry-run"
            [Char] -> ShM ()
sh_cs ([Char] -> ShM ()) -> [Char] -> ShM ()
forall a b. (a -> b) -> a -> b
$ [Char]
"cabal-plan topo | sort"
            Bool -> ShM () -> ShM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
cfgInstallDeps (ShM () -> ShM ()) -> ShM () -> ShM ()
forall a b. (a -> b) -> a -> b
$ [Char] -> ShM ()
sh_cs ([Char] -> ShM ()) -> [Char] -> ShM ()
forall a b. (a -> b) -> a -> b
$ [Char]
"$CABAL v2-build $ARG_COMPILER " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
allFlags [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" --dependencies-only -j2 all"
            [Char] -> ShM ()
sh_cs ([Char] -> ShM ()) -> [Char] -> ShM ()
forall a b. (a -> b) -> a -> b
$ [Char]
"$CABAL v2-build $ARG_COMPILER " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
allFlags [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" all"
            Bool -> ShM () -> ShM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Bool
docspecEnabled Bool -> Bool -> Bool
&& ConstraintSet -> Bool
csDocspec ConstraintSet
cs) (ShM () -> ShM ()) -> ShM () -> ShM ()
forall a b. (a -> b) -> a -> b
$
                CompilerRange -> [Char] -> ShM ()
sh_cs' CompilerRange
docspecRange [Char]
cabalDocspec
            Bool -> ShM () -> ShM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (ConstraintSet -> Bool
csRunTests ConstraintSet
cs) (ShM () -> ShM ()) -> ShM () -> ShM ()
forall a b. (a -> b) -> a -> b
$
                CompilerRange -> [Char] -> ShM ()
sh_cs' CompilerRange
hasTests ([Char] -> ShM ()) -> [Char] -> ShM ()
forall a b. (a -> b) -> a -> b
$ [Char]
"$CABAL v2-test $ARG_COMPILER " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
allFlags [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" all"
            Bool -> ShM () -> ShM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (ConstraintSet -> Bool
csHaddock ConstraintSet
cs) (ShM () -> ShM ()) -> ShM () -> ShM ()
forall a b. (a -> b) -> a -> b
$
                [Char] -> ShM ()
sh_cs ([Char] -> ShM ()) -> [Char] -> ShM ()
forall a b. (a -> b) -> a -> b
$ [Char]
"$CABAL v2-haddock --disable-documentation" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
haddockFlags [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" $ARG_COMPILER " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
withHaddock [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
allFlags [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" all"

        [Char]
-> [Char]
-> [Char]
-> [([Char], [Char])]
-> ListBuilder (Either HsCiError GitHubStep) ()
githubUsesIf [Char]
"save cache" [Char]
"actions/cache/save@v3" [Char]
"always()"
          [ ([Char]
"key", [Char]
"${{ runner.os }}-${{ matrix.compiler }}-${{ github.sha }}")
          , ([Char]
"path", [Char]
"~/.cabal/store")
          ]

    -- assembling everything
    GitHub -> Either HsCiError GitHub
forall a. a -> Either HsCiError a
forall (m :: * -> *) a. Monad m => a -> m a
return GitHub
        { ghName :: [Char]
ghName = [Char]
actionName
        , ghOn :: GitHubOn
ghOn = GitHubOn
            { ghBranches :: [[Char]]
ghBranches = [[Char]]
cfgOnlyBranches
            }
        , ghJobs :: Map [Char] GitHubJob
ghJobs = [([Char], GitHubJob)] -> Map [Char] GitHubJob
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList ([([Char], GitHubJob)] -> Map [Char] GitHubJob)
-> [([Char], GitHubJob)] -> Map [Char] GitHubJob
forall a b. (a -> b) -> a -> b
$ ListBuilder ([Char], GitHubJob) () -> [([Char], GitHubJob)]
forall x. ListBuilder x () -> [x]
buildList (ListBuilder ([Char], GitHubJob) () -> [([Char], GitHubJob)])
-> ListBuilder ([Char], GitHubJob) () -> [([Char], GitHubJob)]
forall a b. (a -> b) -> a -> b
$ do
            ([Char], GitHubJob) -> ListBuilder ([Char], GitHubJob) ()
forall x. x -> ListBuilder x ()
item ([Char]
mainJobName, GitHubJob
                { ghjName :: [Char]
ghjName            = [Char]
actionName [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" - Linux - ${{ matrix.compiler }}"
                  -- NB: The Ubuntu version used in `runs-on` isn't
                  -- particularly important since we use a Docker container.
                , ghjRunsOn :: [Char]
ghjRunsOn          = [Char]
ghcRunsOnVer
                , ghjNeeds :: [[Char]]
ghjNeeds           = []
                , ghjSteps :: [GitHubStep]
ghjSteps           = [GitHubStep]
steps
                , ghjIf :: Maybe [Char]
ghjIf              = Maybe [Char]
forall a. Maybe a
Nothing
                , ghjContainer :: Maybe [Char]
ghjContainer       = [Char] -> Maybe [Char]
forall a. a -> Maybe a
Just ([Char] -> Maybe [Char]) -> [Char] -> Maybe [Char]
forall a b. (a -> b) -> a -> b
$ [Char]
"buildpack-deps:" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
ubuntuVer
                , ghjContinueOnError :: Maybe [Char]
ghjContinueOnError = [Char] -> Maybe [Char]
forall a. a -> Maybe a
Just [Char]
"${{ matrix.allow-failure }}"
                , ghjServices :: Map [Char] GitHubService
ghjServices        = [Map [Char] GitHubService] -> Map [Char] GitHubService
forall a. Monoid a => [a] -> a
mconcat
                    [ [Char] -> GitHubService -> Map [Char] GitHubService
forall k a. k -> a -> Map k a
Map.singleton [Char]
"postgres" GitHubService
postgresService | Bool
cfgPostgres ]
                , ghjTimeout :: Natural
ghjTimeout         = Natural -> Natural -> Natural
forall a. Ord a => a -> a -> a
max Natural
10 Natural
cfgTimeoutMinutes
                , ghjMatrix :: [GitHubMatrixEntry]
ghjMatrix          =
                    [ GitHubMatrixEntry
                        { ghmeCompiler :: CompilerVersion
ghmeCompiler     = CompilerVersion -> CompilerVersion
translateCompilerVersion (CompilerVersion -> CompilerVersion)
-> CompilerVersion -> CompilerVersion
forall a b. (a -> b) -> a -> b
$ CompilerVersion
compiler
                        , ghmeAllowFailure :: Bool
ghmeAllowFailure =
                               CompilerVersion -> Bool
isGHCHead CompilerVersion
compiler
                            Bool -> Bool -> Bool
|| Bool -> (Version -> Bool) -> CompilerVersion -> Bool
forall a. a -> (Version -> a) -> CompilerVersion -> a
maybeGHC Bool
False (Version -> VersionRange -> Bool
`C.withinRange` VersionRange
cfgAllowFailures) CompilerVersion
compiler
                        , ghmeSetupMethod :: SetupMethod
ghmeSetupMethod = if CompilerVersion -> Bool
isGHCUP CompilerVersion
compiler then SetupMethod
GHCUP else SetupMethod
HVRPPA
                        }
                    | CompilerVersion
compiler <- [CompilerVersion] -> [CompilerVersion]
forall a. [a] -> [a]
reverse ([CompilerVersion] -> [CompilerVersion])
-> [CompilerVersion] -> [CompilerVersion]
forall a b. (a -> b) -> a -> b
$ Set CompilerVersion -> [CompilerVersion]
forall a. Set a -> [a]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList Set CompilerVersion
linuxVersions
                    , CompilerVersion
compiler CompilerVersion -> CompilerVersion -> Bool
forall a. Eq a => a -> a -> Bool
/= CompilerVersion
GHCHead -- TODO: Make this work
                                          -- https://github.com/haskell-CI/haskell-ci/issues/458
                    ]
                })
            Bool
-> ListBuilder ([Char], GitHubJob) ()
-> ListBuilder ([Char], GitHubJob) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless ([[Char]] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [[Char]]
cfgIrcChannels) (ListBuilder ([Char], GitHubJob) ()
 -> ListBuilder ([Char], GitHubJob) ())
-> ListBuilder ([Char], GitHubJob) ()
-> ListBuilder ([Char], GitHubJob) ()
forall a b. (a -> b) -> a -> b
$
                [Char]
-> [Char]
-> [Char]
-> Config
-> GitConfig
-> ListBuilder ([Char], GitHubJob) ()
ircJob [Char]
actionName [Char]
mainJobName [Char]
projectName Config
config GitConfig
gitconfig
        }
  where
    actionName :: [Char]
actionName  = [Char] -> Maybe [Char] -> [Char]
forall a. a -> Maybe a -> a
fromMaybe [Char]
"Haskell-CI" Maybe [Char]
cfgGitHubActionName
    mainJobName :: [Char]
mainJobName = [Char]
"linux"

    ubuntuVer :: [Char]
ubuntuVer    = Ubuntu -> [Char]
showUbuntu Ubuntu
cfgUbuntu
    cabalVer :: [Char]
cabalVer     = Maybe Version -> [Char]
dispCabalVersion Maybe Version
cfgCabalInstallVersion
    cabalFullVer :: [Char]
cabalFullVer = Maybe Version -> [Char]
dispCabalVersion (Maybe Version -> [Char]) -> Maybe Version -> [Char]
forall a b. (a -> b) -> a -> b
$ Version -> Version
cabalGhcupVersion (Version -> Version) -> Maybe Version -> Maybe Version
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Version
cfgCabalInstallVersion

    Auxiliary {Bool
[Char]
[URI]
[Package]
CompilerRange
[Char] -> [PrettyField ()]
anyJobUsesPreviewGHC :: Bool
anyJobUsesHeadHackage :: Bool
doctestEnabled :: Bool
docspecEnabled :: Bool
pkgs :: [Package]
extraCabalProjectFields :: [Char] -> [PrettyField ()]
hasTests :: CompilerRange
testShowDetails :: [Char]
runHaddock :: Bool
haddockFlags :: [Char]
projectName :: [Char]
uris :: [URI]
hasLibrary :: Bool
pkgs :: Auxiliary -> [Package]
uris :: Auxiliary -> [URI]
projectName :: Auxiliary -> [Char]
doctestEnabled :: Auxiliary -> Bool
docspecEnabled :: Auxiliary -> Bool
hasTests :: Auxiliary -> CompilerRange
hasLibrary :: Auxiliary -> Bool
extraCabalProjectFields :: Auxiliary -> [Char] -> [PrettyField ()]
testShowDetails :: Auxiliary -> [Char]
anyJobUsesHeadHackage :: Auxiliary -> Bool
anyJobUsesPreviewGHC :: Auxiliary -> Bool
runHaddock :: Auxiliary -> Bool
haddockFlags :: Auxiliary -> [Char]
..} = Config -> Project URI Void Package -> JobVersions -> Auxiliary
auxiliary Config
config Project URI Void Package
prj JobVersions
jobs

    anyGHCJS :: Bool
anyGHCJS = (CompilerVersion -> Bool) -> Set CompilerVersion -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any CompilerVersion -> Bool
isGHCJS Set CompilerVersion
allVersions
    anyGHCUP :: Bool
anyGHCUP = (CompilerVersion -> Bool) -> Set CompilerVersion -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any CompilerVersion -> Bool
isGHCUP Set CompilerVersion
allVersions
    allGHCUP :: Bool
allGHCUP = (CompilerVersion -> Bool) -> Set CompilerVersion -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all CompilerVersion -> Bool
isGHCUP Set CompilerVersion
allVersions

    -- Generate a setup block for hvr-ppa or ghcup, or both.
    setup :: [Sh] -> [Sh] -> ShM ()
    setup :: [Sh] -> [Sh] -> ShM ()
setup [Sh]
hvrppa [Sh]
ghcup
        | Bool
allGHCUP     = (Sh -> ShM ()) -> [Sh] -> ShM ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
(a -> f b) -> t a -> f ()
traverse_ Sh -> ShM ()
liftSh [Sh]
ghcup
        | Bool -> Bool
not Bool
anyGHCUP = (Sh -> ShM ()) -> [Sh] -> ShM ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
(a -> f b) -> t a -> f ()
traverse_ Sh -> ShM ()
liftSh [Sh]
hvrppa
        -- SC2192: ${{ ...}} will match (ShellCheck think it doesn't)
        -- SC2129: individual redirects
        -- SC2296: Parameter expansions can't start with {. Double check syntax. -- ${{ }} in YAML templating.
        | Bool
otherwise    = [Integer] -> [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Integer] -> [Char] -> m ()
sh' [Integer
2193, Integer
2129, Integer
2296] ([Char] -> ShM ()) -> [Char] -> ShM ()
forall a b. (a -> b) -> a -> b
$ [[Char]] -> [Char]
unlines ([[Char]] -> [Char]) -> [[Char]] -> [Char]
forall a b. (a -> b) -> a -> b
$
            [ [Char]
"if [ \"${{ matrix.setup-method }}\" = ghcup ]; then"
            ] [[Char]] -> [[Char]] -> [[Char]]
forall a. [a] -> [a] -> [a]
++
            [ [Char]
"  " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Sh -> [Char]
shToString Sh
s
            | Sh
s <- [Sh]
ghcup
            ] [[Char]] -> [[Char]] -> [[Char]]
forall a. [a] -> [a] -> [a]
++
            [ [Char]
"else"
            ] [[Char]] -> [[Char]] -> [[Char]]
forall a. [a] -> [a] -> [a]
++
            [ [Char]
"  " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Sh -> [Char]
shToString Sh
s
            | Sh
s <- [Sh]
hvrppa
            ] [[Char]] -> [[Char]] -> [[Char]]
forall a. [a] -> [a] -> [a]
++
            [ [Char]
"fi"
            ]

    -- job to be setup with ghcup
    isGHCUP :: CompilerVersion -> Bool
    isGHCUP :: CompilerVersion -> Bool
isGHCUP CompilerVersion
v = CompilerVersion -> CompilerRange -> Bool
compilerWithinRange CompilerVersion
v (CompilerRange
RangeGHC CompilerRange -> CompilerRange -> CompilerRange
forall a. Lattice a => a -> a -> a
/\ VersionRange -> CompilerRange
Range VersionRange
cfgGhcupJobs)

    -- step primitives
    githubRun' :: String -> Map.Map String String ->  ShM () -> ListBuilder (Either HsCiError GitHubStep) ()
    githubRun' :: [Char]
-> Map [Char] [Char]
-> ShM ()
-> ListBuilder (Either HsCiError GitHubStep) ()
githubRun' [Char]
name Map [Char] [Char]
env ShM ()
shm = Either HsCiError GitHubStep
-> ListBuilder (Either HsCiError GitHubStep) ()
forall x. x -> ListBuilder x ()
item (Either HsCiError GitHubStep
 -> ListBuilder (Either HsCiError GitHubStep) ())
-> Either HsCiError GitHubStep
-> ListBuilder (Either HsCiError GitHubStep) ()
forall a b. (a -> b) -> a -> b
$ do
        [Sh]
shs <- ShM () -> Either HsCiError [Sh]
forall e (m :: * -> *).
(MonadErr e m, FromHsCiError e) =>
ShM () -> m [Sh]
runSh ShM ()
shm
        GitHubStep -> Either HsCiError GitHubStep
forall a. a -> Either HsCiError a
forall (m :: * -> *) a. Monad m => a -> m a
return (GitHubStep -> Either HsCiError GitHubStep)
-> GitHubStep -> Either HsCiError GitHubStep
forall a b. (a -> b) -> a -> b
$ [Char] -> Either GitHubRun GitHubUses -> GitHubStep
GitHubStep [Char]
name (Either GitHubRun GitHubUses -> GitHubStep)
-> Either GitHubRun GitHubUses -> GitHubStep
forall a b. (a -> b) -> a -> b
$ GitHubRun -> Either GitHubRun GitHubUses
forall a b. a -> Either a b
Left (GitHubRun -> Either GitHubRun GitHubUses)
-> GitHubRun -> Either GitHubRun GitHubUses
forall a b. (a -> b) -> a -> b
$ [Sh] -> Map [Char] [Char] -> GitHubRun
GitHubRun [Sh]
shs Map [Char] [Char]
env

    githubRun :: String -> ShM () -> ListBuilder (Either HsCiError GitHubStep) ()
    githubRun :: [Char] -> ShM () -> ListBuilder (Either HsCiError GitHubStep) ()
githubRun [Char]
name = [Char]
-> Map [Char] [Char]
-> ShM ()
-> ListBuilder (Either HsCiError GitHubStep) ()
githubRun' [Char]
name Map [Char] [Char]
forall a. Monoid a => a
mempty

    githubUses :: String -> String -> [(String, String)] -> ListBuilder (Either HsCiError GitHubStep) ()
    githubUses :: [Char]
-> [Char]
-> [([Char], [Char])]
-> ListBuilder (Either HsCiError GitHubStep) ()
githubUses [Char]
name [Char]
action [([Char], [Char])]
with = Either HsCiError GitHubStep
-> ListBuilder (Either HsCiError GitHubStep) ()
forall x. x -> ListBuilder x ()
item (Either HsCiError GitHubStep
 -> ListBuilder (Either HsCiError GitHubStep) ())
-> Either HsCiError GitHubStep
-> ListBuilder (Either HsCiError GitHubStep) ()
forall a b. (a -> b) -> a -> b
$ GitHubStep -> Either HsCiError GitHubStep
forall a. a -> Either HsCiError a
forall (m :: * -> *) a. Monad m => a -> m a
return (GitHubStep -> Either HsCiError GitHubStep)
-> GitHubStep -> Either HsCiError GitHubStep
forall a b. (a -> b) -> a -> b
$
        [Char] -> Either GitHubRun GitHubUses -> GitHubStep
GitHubStep [Char]
name (Either GitHubRun GitHubUses -> GitHubStep)
-> Either GitHubRun GitHubUses -> GitHubStep
forall a b. (a -> b) -> a -> b
$ GitHubUses -> Either GitHubRun GitHubUses
forall a b. b -> Either a b
Right (GitHubUses -> Either GitHubRun GitHubUses)
-> GitHubUses -> Either GitHubRun GitHubUses
forall a b. (a -> b) -> a -> b
$ [Char] -> Maybe [Char] -> Map [Char] [Char] -> GitHubUses
GitHubUses [Char]
action Maybe [Char]
forall a. Maybe a
Nothing ([([Char], [Char])] -> Map [Char] [Char]
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList [([Char], [Char])]
with)

    githubUsesIf :: String -> String -> String -> [(String, String)] -> ListBuilder (Either HsCiError GitHubStep) ()
    githubUsesIf :: [Char]
-> [Char]
-> [Char]
-> [([Char], [Char])]
-> ListBuilder (Either HsCiError GitHubStep) ()
githubUsesIf [Char]
name [Char]
action [Char]
if_ [([Char], [Char])]
with = Either HsCiError GitHubStep
-> ListBuilder (Either HsCiError GitHubStep) ()
forall x. x -> ListBuilder x ()
item (Either HsCiError GitHubStep
 -> ListBuilder (Either HsCiError GitHubStep) ())
-> Either HsCiError GitHubStep
-> ListBuilder (Either HsCiError GitHubStep) ()
forall a b. (a -> b) -> a -> b
$ GitHubStep -> Either HsCiError GitHubStep
forall a. a -> Either HsCiError a
forall (m :: * -> *) a. Monad m => a -> m a
return (GitHubStep -> Either HsCiError GitHubStep)
-> GitHubStep -> Either HsCiError GitHubStep
forall a b. (a -> b) -> a -> b
$
        [Char] -> Either GitHubRun GitHubUses -> GitHubStep
GitHubStep [Char]
name (Either GitHubRun GitHubUses -> GitHubStep)
-> Either GitHubRun GitHubUses -> GitHubStep
forall a b. (a -> b) -> a -> b
$ GitHubUses -> Either GitHubRun GitHubUses
forall a b. b -> Either a b
Right (GitHubUses -> Either GitHubRun GitHubUses)
-> GitHubUses -> Either GitHubRun GitHubUses
forall a b. (a -> b) -> a -> b
$ [Char] -> Maybe [Char] -> Map [Char] [Char] -> GitHubUses
GitHubUses [Char]
action ([Char] -> Maybe [Char]
forall a. a -> Maybe a
Just [Char]
if_) ([([Char], [Char])] -> Map [Char] [Char]
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList [([Char], [Char])]
with)

    -- shell primitives
    echo_to' :: FilePath -> String -> String
    echo_to' :: [Char] -> [Char] -> [Char]
echo_to' [Char]
fp [Char]
s = [Char]
"echo " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char] -> [Char]
forall a. Show a => a -> [Char]
show [Char]
s [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" >> " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
fp

    echo_to :: FilePath -> String -> ShM ()
    echo_to :: [Char] -> [Char] -> ShM ()
echo_to [Char]
fp [Char]
s = [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh ([Char] -> ShM ()) -> [Char] -> ShM ()
forall a b. (a -> b) -> a -> b
$ [Char] -> [Char] -> [Char]
echo_to' [Char]
fp [Char]
s

    echo_if_to :: CompilerRange -> FilePath -> String -> ShM ()
    echo_if_to :: CompilerRange -> [Char] -> [Char] -> ShM ()
echo_if_to CompilerRange
range [Char]
fp [Char]
s = CompilerRange -> [Char] -> ShM ()
sh_if CompilerRange
range ([Char] -> ShM ()) -> [Char] -> ShM ()
forall a b. (a -> b) -> a -> b
$ [Char] -> [Char] -> [Char]
echo_to' [Char]
fp [Char]
s

    change_dir_if :: CompilerRange -> String -> ShM ()
    change_dir_if :: CompilerRange -> [Char] -> ShM ()
change_dir_if CompilerRange
range [Char]
dir = CompilerRange -> [Char] -> ShM ()
sh_if CompilerRange
range ([Char]
"cd " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
dir [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" || false")

    tell_env' :: String -> String -> String
    tell_env' :: [Char] -> [Char] -> [Char]
tell_env' [Char]
k [Char]
v = [Char]
"echo " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char] -> [Char]
forall a. Show a => a -> [Char]
show ([Char]
k [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"=" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
v) [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" >> \"$GITHUB_ENV\""

    tell_env :: String -> String -> ShM ()
    tell_env :: [Char] -> [Char] -> ShM ()
tell_env [Char]
k [Char]
v = [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh ([Char] -> ShM ()) -> [Char] -> ShM ()
forall a b. (a -> b) -> a -> b
$ [Char] -> [Char] -> [Char]
tell_env' [Char]
k [Char]
v

    if_then_else :: CompilerRange -> String -> String -> ShM ()
    if_then_else :: CompilerRange -> [Char] -> [Char] -> ShM ()
if_then_else CompilerRange
range [Char]
con [Char]
alt
        | (CompilerVersion -> Bool) -> Set CompilerVersion -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (CompilerVersion -> CompilerRange -> Bool
`compilerWithinRange` CompilerRange
range) Set CompilerVersion
allVersions       = [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh [Char]
con
        | Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ (CompilerVersion -> Bool) -> Set CompilerVersion -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (CompilerVersion -> CompilerRange -> Bool
`compilerWithinRange` CompilerRange
range) Set CompilerVersion
allVersions = [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh [Char]
alt
        | Bool
otherwise = [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh ([Char] -> ShM ()) -> [Char] -> ShM ()
forall a b. (a -> b) -> a -> b
$ [[Char]] -> [Char]
unwords
        [ [Char]
"if ["
        , Set CompilerVersion -> CompilerRange -> [Char]
compilerVersionArithPredicate Set CompilerVersion
allVersions CompilerRange
range
        , [Char]
"-ne 0 ]"
        , [Char]
"; then"
        , [Char]
con
        , [Char]
";"
        , [Char]
"else"
        , [Char]
alt
        , [Char]
";"
        , [Char]
"fi"
        ]

    sh_if :: CompilerRange -> String -> ShM ()
    sh_if :: CompilerRange -> [Char] -> ShM ()
sh_if CompilerRange
range [Char]
con
        | (CompilerVersion -> Bool) -> Set CompilerVersion -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (CompilerVersion -> CompilerRange -> Bool
`compilerWithinRange` CompilerRange
range) Set CompilerVersion
allVersions       = [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh [Char]
con
        | Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ (CompilerVersion -> Bool) -> Set CompilerVersion -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (CompilerVersion -> CompilerRange -> Bool
`compilerWithinRange` CompilerRange
range) Set CompilerVersion
allVersions = () -> ShM ()
forall a. a -> ShM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
        | Bool
otherwise = [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh ([Char] -> ShM ()) -> [Char] -> ShM ()
forall a b. (a -> b) -> a -> b
$ [[Char]] -> [Char]
unwords
        [ [Char]
"if ["
        , Set CompilerVersion -> CompilerRange -> [Char]
compilerVersionArithPredicate Set CompilerVersion
allVersions CompilerRange
range
        , [Char]
"-ne 0 ]"
        , [Char]
"; then"
        , [Char]
con
        , [Char]
";"
        , [Char]
"fi"
        ]

    -- Needed to work around haskell/cabal#6214
    withHaddock :: String
    withHaddock :: [Char]
withHaddock = [Char]
"--with-haddock $HADDOCK"

    cabalDocspec :: String
    cabalDocspec :: [Char]
cabalDocspec =
      let docspecOptions :: [[Char]]
docspecOptions = DocspecConfig -> [[Char]]
cfgDocspecOptions DocspecConfig
cfgDocspec in
      [[Char]] -> [Char]
unwords ([[Char]] -> [Char]) -> [[Char]] -> [Char]
forall a b. (a -> b) -> a -> b
$ [Char]
"cabal-docspec $ARG_COMPILER" [Char] -> [[Char]] -> [[Char]]
forall a. a -> [a] -> [a]
: [[Char]]
docspecOptions

    docspecRange :: CompilerRange
    docspecRange :: CompilerRange
docspecRange = VersionRange -> CompilerRange
Range (DocspecConfig -> VersionRange
cfgDocspecEnabled DocspecConfig
cfgDocspec)

postgresService :: GitHubService
postgresService :: GitHubService
postgresService = GitHubService
    { ghServImage :: [Char]
ghServImage   = [Char]
"postgres:14"
    , ghServOptions :: Maybe [Char]
ghServOptions = [Char] -> Maybe [Char]
forall a. a -> Maybe a
Just [Char]
"--health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5"
    , ghServEnv :: Map [Char] [Char]
ghServEnv     = [([Char], [Char])] -> Map [Char] [Char]
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList
          [ ([Char]
"POSTGRES_PASSWORD", [Char]
"postgres")
          ]
    }

ircJob :: String -> String -> String -> Config -> GitConfig -> ListBuilder (String, GitHubJob) ()
ircJob :: [Char]
-> [Char]
-> [Char]
-> Config
-> GitConfig
-> ListBuilder ([Char], GitHubJob) ()
ircJob [Char]
actionName [Char]
mainJobName [Char]
projectName Config
cfg GitConfig
gitconfig = ([Char], GitHubJob) -> ListBuilder ([Char], GitHubJob) ()
forall x. x -> ListBuilder x ()
item ([Char]
"irc", GitHubJob
    { ghjName :: [Char]
ghjName            = [Char]
actionName [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" (IRC notification)"
    , ghjRunsOn :: [Char]
ghjRunsOn          = [Char]
ghcRunsOnVer
    , ghjNeeds :: [[Char]]
ghjNeeds           = [[Char]
mainJobName]
    , ghjIf :: Maybe [Char]
ghjIf              = Maybe [Char]
jobCondition
    , ghjContainer :: Maybe [Char]
ghjContainer       = Maybe [Char]
forall a. Maybe a
Nothing
    , ghjContinueOnError :: Maybe [Char]
ghjContinueOnError = Maybe [Char]
forall a. Maybe a
Nothing
    , ghjMatrix :: [GitHubMatrixEntry]
ghjMatrix          = []
    , ghjServices :: Map [Char] GitHubService
ghjServices        = Map [Char] GitHubService
forall a. Monoid a => a
mempty
    , ghjSteps :: [GitHubStep]
ghjSteps           = [ [Char] -> Bool -> GitHubStep
ircStep [Char]
serverChannelName Bool
success
                           | [Char]
serverChannelName <- [[Char]]
serverChannelNames
                           , Bool
success <- [Bool
True, Bool
False]
                           ]
    , ghjTimeout :: Natural
ghjTimeout         = Natural
10
    })
  where
    serverChannelNames :: [[Char]]
serverChannelNames = Config -> [[Char]]
cfgIrcChannels Config
cfg

    jobCondition :: Maybe String
    jobCondition :: Maybe [Char]
jobCondition
        | Config -> Bool
cfgIrcIfInOriginRepo Config
cfg
        , Just Text
url <- Text -> Map Text Text -> Maybe Text
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup Text
"origin" (GitConfig -> Map Text Text
gitCfgRemotes GitConfig
gitconfig)
        , Just Text
repo <- Text -> Maybe Text
parseGitHubRepo Text
url

        = [Char] -> Maybe [Char]
forall a. a -> Maybe a
Just
        ([Char] -> Maybe [Char]) -> [Char] -> Maybe [Char]
forall a b. (a -> b) -> a -> b
$ [Char]
"${{ always() && (github.repository == '" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ Text -> [Char]
T.unpack Text
repo [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"') }}"

        | Bool
otherwise
        = [Char] -> Maybe [Char]
forall a. a -> Maybe a
Just [Char]
"${{ always() }}"
        -- Use always() above to ensure that the IRC job will still run even if
        -- the build job itself fails (see #437).

    ircStep :: String -> Bool -> GitHubStep
    ircStep :: [Char] -> Bool -> GitHubStep
ircStep [Char]
serverChannelName Bool
success =
        let ([Char]
serverName, [Char]
channelName) = (Char -> Bool) -> [Char] -> ([Char], [Char])
forall a. (a -> Bool) -> [a] -> ([a], [a])
break (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'#') [Char]
serverChannelName

            result :: [Char]
result | Bool
success   = [Char]
"success"
                   | Bool
otherwise = [Char]
"failure"

            resultPastTense :: [Char]
resultPastTense | Bool
success   = [Char]
"succeeded"
                            | Bool
otherwise = [Char]
"failed"

            eqCheck :: [Char]
eqCheck | Bool
success   = [Char]
"=="
                    | Bool
otherwise = [Char]
"!=" in

        [Char] -> Either GitHubRun GitHubUses -> GitHubStep
GitHubStep ([Char]
"IRC " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
result [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" notification (" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
serverChannelName [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
")") (Either GitHubRun GitHubUses -> GitHubStep)
-> Either GitHubRun GitHubUses -> GitHubStep
forall a b. (a -> b) -> a -> b
$ GitHubUses -> Either GitHubRun GitHubUses
forall a b. b -> Either a b
Right (GitHubUses -> Either GitHubRun GitHubUses)
-> GitHubUses -> Either GitHubRun GitHubUses
forall a b. (a -> b) -> a -> b
$
        [Char] -> Maybe [Char] -> Map [Char] [Char] -> GitHubUses
GitHubUses [Char]
"Gottox/irc-message-action@v2"
                   ([Char] -> Maybe [Char]
forall a. a -> Maybe a
Just ([Char] -> Maybe [Char]) -> [Char] -> Maybe [Char]
forall a b. (a -> b) -> a -> b
$ [Char]
"needs." [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
mainJobName [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
".result " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
eqCheck [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" 'success'") (Map [Char] [Char] -> GitHubUses)
-> Map [Char] [Char] -> GitHubUses
forall a b. (a -> b) -> a -> b
$
        [([Char], [Char])] -> Map [Char] [Char]
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList ([([Char], [Char])] -> Map [Char] [Char])
-> [([Char], [Char])] -> Map [Char] [Char]
forall a b. (a -> b) -> a -> b
$ ListBuilder ([Char], [Char]) () -> [([Char], [Char])]
forall x. ListBuilder x () -> [x]
buildList (ListBuilder ([Char], [Char]) () -> [([Char], [Char])])
-> ListBuilder ([Char], [Char]) () -> [([Char], [Char])]
forall a b. (a -> b) -> a -> b
$ do
            ([Char], [Char]) -> ListBuilder ([Char], [Char]) ()
forall x. x -> ListBuilder x ()
item ([Char]
"server",   [Char]
serverName)
            ([Char], [Char]) -> ListBuilder ([Char], [Char]) ()
forall x. x -> ListBuilder x ()
item ([Char]
"channel",  [Char]
channelName)
            ([Char], [Char]) -> ListBuilder ([Char], [Char]) ()
forall x. x -> ListBuilder x ()
item ([Char]
"nickname", [Char] -> Maybe [Char] -> [Char]
forall a. a -> Maybe a -> a
fromMaybe [Char]
"github-actions" (Maybe [Char] -> [Char]) -> Maybe [Char] -> [Char]
forall a b. (a -> b) -> a -> b
$ Config -> Maybe [Char]
cfgIrcNickname Config
cfg)
            Maybe [Char]
-> ([Char] -> ListBuilder ([Char], [Char]) ())
-> ListBuilder ([Char], [Char]) ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ (Config -> Maybe [Char]
cfgIrcPassword Config
cfg) (([Char] -> ListBuilder ([Char], [Char]) ())
 -> ListBuilder ([Char], [Char]) ())
-> ([Char] -> ListBuilder ([Char], [Char]) ())
-> ListBuilder ([Char], [Char]) ()
forall a b. (a -> b) -> a -> b
$ \[Char]
p ->
                ([Char], [Char]) -> ListBuilder ([Char], [Char]) ()
forall x. x -> ListBuilder x ()
item ([Char]
"sasl_password", [Char]
p)
            ([Char], [Char]) -> ListBuilder ([Char], [Char]) ()
forall x. x -> ListBuilder x ()
item ([Char]
"message",  [Char]
"\x0313" [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
projectName [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"\x03/\x0306${{ github.ref }}\x03 "
                                       [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"\x0314${{ github.sha }}\x03 "
                                       [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }} "
                                       [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
"The build " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
resultPastTense [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
".")

catCmd :: FilePath -> String -> String
catCmd :: [Char] -> [Char] -> [Char]
catCmd [Char]
path [Char]
contents = [[Char]] -> [Char]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
    [ [Char]
"cat >> " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
path [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ [Char]
" <<EOF\n"
    , [Char]
contents
    , [Char]
"EOF"
    ]

cat :: FilePath -> String -> ShM ()
cat :: [Char] -> [Char] -> ShM ()
cat [Char]
path [Char]
contents = [Char] -> ShM ()
forall (m :: * -> *). MonadSh m => [Char] -> m ()
sh ([Char] -> ShM ()) -> [Char] -> ShM ()
forall a b. (a -> b) -> a -> b
$ [Char] -> [Char] -> [Char]
catCmd [Char]
path [Char]
contents

-- | GitHub is very lenient and undocumented. We accept something.
-- Please, write a patch, if you need an extra scheme to be accepted.
--
-- >>> parseGitHubRepo "git@github.com:haskell-CI/haskell-ci.git"
-- Just "haskell-CI/haskell-ci"
--
-- >>> parseGitHubRepo "git@github.com:haskell-CI/haskell-ci"
-- Just "haskell-CI/haskell-ci"
--
-- >>> parseGitHubRepo "https://github.com/haskell-CI/haskell-ci.git"
-- Just "haskell-CI/haskell-ci"
--
-- >>> parseGitHubRepo "https://github.com/haskell-CI/haskell-ci"
-- Just "haskell-CI/haskell-ci"
--
-- >>> parseGitHubRepo "git://github.com/haskell-CI/haskell-ci"
-- Just "haskell-CI/haskell-ci"
--
parseGitHubRepo :: Text -> Maybe Text
parseGitHubRepo :: Text -> Maybe Text
parseGitHubRepo Text
t =
    ([Char] -> Maybe Text)
-> (Text -> Maybe Text) -> Either [Char] Text -> Maybe Text
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (Maybe Text -> [Char] -> Maybe Text
forall a b. a -> b -> a
const Maybe Text
forall a. Maybe a
Nothing) Text -> Maybe Text
forall a. a -> Maybe a
Just (Either [Char] Text -> Maybe Text)
-> Either [Char] Text -> Maybe Text
forall a b. (a -> b) -> a -> b
$ Parser Text -> Text -> Either [Char] Text
forall a. Parser a -> Text -> Either [Char] a
Atto.parseOnly (Parser Text
parser Parser Text -> Parser Text () -> Parser Text
forall a b. Parser Text a -> Parser Text b -> Parser Text a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser Text ()
forall t. Chunk t => Parser t ()
Atto.endOfInput) Text
t
  where
    parser :: Atto.Parser Text
    parser :: Parser Text
parser = Parser Text
sshP Parser Text -> Parser Text -> Parser Text
forall a. Parser Text a -> Parser Text a -> Parser Text a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser Text
httpsP

    sshP :: Atto.Parser Text
    sshP :: Parser Text
sshP = do
        Maybe Text
_ <- Parser Text -> Parser Text (Maybe Text)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (Text -> Parser Text
Atto.string Text
"git://")
        Text
_ <- Text -> Parser Text
Atto.string Text
"git@github.com:"
        Text
repo <- (Char -> Bool) -> Parser Text
Atto.takeWhile (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= Char
'.')
        Maybe Text
_ <- Parser Text -> Parser Text (Maybe Text)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (Text -> Parser Text
Atto.string Text
".git")
        Text -> Parser Text
forall a. a -> Parser Text a
forall (m :: * -> *) a. Monad m => a -> m a
return Text
repo

    httpsP :: Atto.Parser Text
    httpsP :: Parser Text
httpsP = do
        Text
_ <- Text -> Parser Text
Atto.string Text
"https" Parser Text -> Parser Text -> Parser Text
forall a. Parser Text a -> Parser Text a -> Parser Text a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Text -> Parser Text
Atto.string Text
"git"
        Text
_ <- Text -> Parser Text
Atto.string Text
"://github.com/"
        Text
repo <- (Char -> Bool) -> Parser Text
Atto.takeWhile (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= Char
'.')
        Maybe Text
_ <- Parser Text -> Parser Text (Maybe Text)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (Text -> Parser Text
Atto.string Text
".git")
        Text -> Parser Text
forall a. a -> Parser Text a
forall (m :: * -> *) a. Monad m => a -> m a
return Text
repo

-- NB: The Ubuntu version used in `runs-on` isn't particularly important since
-- we use a Docker container. We do make an attempt to keep it relatively up to
-- date to ensure that it runs on a version of Ubuntu that GitHub Actions
-- runners support.
ghcRunsOnVer :: String
ghcRunsOnVer :: [Char]
ghcRunsOnVer = [Char]
"ubuntu-20.04"