{-# LANGUAGE NamedFieldPuns  #-}
{-# LANGUAGE RecordWildCards #-}
{-# OPTIONS_GHC -Wno-unused-matches #-}
module HaskellCI.Bash (
    makeBash
) where

import HaskellCI.Prelude

import qualified Data.Set                        as S
import qualified Distribution.Fields.Pretty      as C
import qualified Distribution.Package            as C
import qualified Distribution.Types.VersionRange as C
import qualified Distribution.Version            as C

import Cabal.Project
import HaskellCI.Auxiliary
import HaskellCI.Bash.Template
import HaskellCI.Compiler
import HaskellCI.Config
import HaskellCI.Config.ConstraintSet
import HaskellCI.Config.Doctest
import HaskellCI.Config.Installed
import HaskellCI.Config.PackageScope
import HaskellCI.Jobs
import HaskellCI.List
import HaskellCI.Package
import HaskellCI.Sh
import HaskellCI.ShVersionRange
import HaskellCI.Tools

{-
Bash-specific notes:

* We use -j for parallelism, as the exact number of cores depends on the
  particular machine the script is being run on.
-}

makeBash
    :: [String]
    -> Config
    -> Project URI Void Package
    -> JobVersions
    -> Either ShError Z -- TODO: writer
makeBash :: [String]
-> Config
-> Project URI Void Package
-> JobVersions
-> Either ShError Z
makeBash [String]
_argv config :: Config
config@Config {Bool
String
[String]
[PrettyField ()]
[PackageName]
[Installed]
[ConstraintSet]
Maybe String
Maybe Version
Maybe Jobs
VersionRange
Set String
Set Version
Set Fold
Map Version String
Ubuntu
PackageScope
HLintConfig
DoctestConfig
DocspecConfig
CopyFields
TestedWithJobs
cfgGitHubActionName :: Config -> Maybe String
cfgRawTravis :: Config -> String
cfgRawProject :: Config -> [PrettyField ()]
cfgConstraintSets :: Config -> [ConstraintSet]
cfgHLint :: Config -> HLintConfig
cfgDocspec :: Config -> DocspecConfig
cfgDoctest :: Config -> DoctestConfig
cfgErrorMissingMethods :: Config -> PackageScope
cfgInsertVersion :: Config -> Bool
cfgGitHubPatches :: Config -> [String]
cfgTravisPatches :: Config -> [String]
cfgApt :: Config -> Set String
cfgOsx :: Config -> Set Version
cfgLastInSeries :: Config -> Bool
cfgAllowFailures :: Config -> VersionRange
cfgEnv :: Config -> Map Version String
cfgGoogleChrome :: Config -> Bool
cfgPostgres :: Config -> Bool
cfgGhcHead :: Config -> Bool
cfgFolds :: Config -> Set Fold
cfgProjectName :: Config -> Maybe String
cfgEmailNotifications :: Config -> Bool
cfgIrcIfInOriginRepo :: Config -> Bool
cfgIrcChannels :: Config -> [String]
cfgOnlyBranches :: Config -> [String]
cfgCheck :: Config -> Bool
cfgTestOutputDirect :: Config -> Bool
cfgGhcjsTools :: Config -> [PackageName]
cfgGhcjsTests :: Config -> Bool
cfgHeadHackage :: Config -> VersionRange
cfgUnconstrainted :: Config -> VersionRange
cfgNoTestsNoBench :: Config -> VersionRange
cfgHaddock :: Config -> VersionRange
cfgBenchmarks :: Config -> VersionRange
cfgRunTests :: Config -> VersionRange
cfgTests :: Config -> VersionRange
cfgInstalled :: Config -> [Installed]
cfgInstallDeps :: Config -> Bool
cfgCache :: Config -> Bool
cfgSubmodules :: Config -> Bool
cfgLocalGhcOptions :: Config -> [String]
cfgCopyFields :: Config -> CopyFields
cfgTestedWith :: Config -> TestedWithJobs
cfgUbuntu :: Config -> Ubuntu
cfgJobs :: Config -> Maybe Jobs
cfgCabalInstallVersion :: Config -> Maybe Version
cfgGitHubActionName :: Maybe String
cfgRawTravis :: String
cfgRawProject :: [PrettyField ()]
cfgConstraintSets :: [ConstraintSet]
cfgHLint :: HLintConfig
cfgDocspec :: DocspecConfig
cfgDoctest :: DoctestConfig
cfgErrorMissingMethods :: PackageScope
cfgInsertVersion :: Bool
cfgGitHubPatches :: [String]
cfgTravisPatches :: [String]
cfgApt :: Set String
cfgOsx :: Set Version
cfgLastInSeries :: Bool
cfgAllowFailures :: VersionRange
cfgEnv :: Map Version String
cfgGoogleChrome :: Bool
cfgPostgres :: Bool
cfgGhcHead :: Bool
cfgFolds :: Set Fold
cfgProjectName :: Maybe String
cfgEmailNotifications :: Bool
cfgIrcIfInOriginRepo :: Bool
cfgIrcChannels :: [String]
cfgOnlyBranches :: [String]
cfgCheck :: Bool
cfgTestOutputDirect :: Bool
cfgGhcjsTools :: [PackageName]
cfgGhcjsTests :: Bool
cfgHeadHackage :: VersionRange
cfgUnconstrainted :: VersionRange
cfgNoTestsNoBench :: VersionRange
cfgHaddock :: VersionRange
cfgBenchmarks :: VersionRange
cfgRunTests :: VersionRange
cfgTests :: VersionRange
cfgInstalled :: [Installed]
cfgInstallDeps :: Bool
cfgCache :: Bool
cfgSubmodules :: Bool
cfgLocalGhcOptions :: [String]
cfgCopyFields :: CopyFields
cfgTestedWith :: TestedWithJobs
cfgUbuntu :: Ubuntu
cfgJobs :: Maybe Jobs
cfgCabalInstallVersion :: Maybe Version
..} Project URI Void Package
prj jobs :: JobVersions
jobs@JobVersions {Set Version
Set CompilerVersion
omittedOsxVersions :: JobVersions -> Set Version
osxVersions :: JobVersions -> Set Version
versions :: JobVersions -> Set CompilerVersion
omittedOsxVersions :: Set Version
osxVersions :: Set Version
versions :: Set CompilerVersion
..} = do
    [String]
blocks <- (Either ShError [Sh] -> Either ShError String)
-> [Either ShError [Sh]] -> Either ShError [String]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse (([Sh] -> String) -> Either ShError [Sh] -> Either ShError String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [Sh] -> String
shsToList) ([Either ShError [Sh]] -> Either ShError [String])
-> [Either ShError [Sh]] -> Either ShError [String]
forall a b. (a -> b) -> a -> b
$ ListBuilder (Either ShError [Sh]) () -> [Either ShError [Sh]]
forall x. ListBuilder x () -> [x]
buildList (ListBuilder (Either ShError [Sh]) () -> [Either ShError [Sh]])
-> ListBuilder (Either ShError [Sh]) () -> [Either ShError [Sh]]
forall a b. (a -> b) -> a -> b
$ do
        -- install doctest
        Bool
-> ListBuilder (Either ShError [Sh]) ()
-> ListBuilder (Either ShError [Sh]) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
doctestEnabled (ListBuilder (Either ShError [Sh]) ()
 -> ListBuilder (Either ShError [Sh]) ())
-> ListBuilder (Either ShError [Sh]) ()
-> ListBuilder (Either ShError [Sh]) ()
forall a b. (a -> b) -> a -> b
$ String -> ShM () -> ListBuilder (Either ShError [Sh]) ()
step String
"install doctest" (ShM () -> ListBuilder (Either ShError [Sh]) ())
-> ShM () -> ListBuilder (Either ShError [Sh]) ()
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
            String -> ShM ()
forall (m :: * -> *). MonadSh m => String -> m ()
comment String
"install doctest"
            CompilerRange -> String -> ShM ()
run_cmd_if CompilerRange
range String
"$CABAL v2-install $ARG_COMPILER --ignore-project -j doctest --constraint='doctest ^>=0.17'"
            CompilerRange -> String -> ShM ()
run_cmd_if CompilerRange
range String
"doctest --version"

        -- install hlint
        -- TODO

        -- autoreconf ...
        -- hmm, source is read-only...

        String -> ShM () -> ListBuilder (Either ShError [Sh]) ()
step String
"initial cabal.project for sdist" (ShM () -> ListBuilder (Either ShError [Sh]) ())
-> ShM () -> ListBuilder (Either ShError [Sh]) ()
forall a b. (a -> b) -> a -> b
$ do
            String -> ShM ()
change_dir String
"$BUILDDIR"
            String -> ShM ()
run_cmd String
"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 -> String -> String -> 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) String
"cabal.project" (String -> ShM ()) -> String -> ShM ()
forall a b. (a -> b) -> a -> b
$ String
"packages: $SRCDIR/" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Package -> String
pkgDir Package
pkg
            String -> ShM ()
run_cmd String
"cat cabal.project"

        -- sdist
        String -> ShM () -> ListBuilder (Either ShError [Sh]) ()
step String
"sdist" (ShM () -> ListBuilder (Either ShError [Sh]) ())
-> ShM () -> ListBuilder (Either ShError [Sh]) ()
forall a b. (a -> b) -> a -> b
$ do
            String -> ShM ()
run_cmd String
"mkdir -p \"$BUILDDIR/sdist\""
            -- TODO: check if cabal-install-3.4 can be run on read only system
            String -> ShM ()
run_cmd String
"$CABAL sdist all --output-dir \"$BUILDDIR/sdist\""

        -- find and unpack sdist
        String -> ShM () -> ListBuilder (Either ShError [Sh]) ()
step String
"unpack" (ShM () -> ListBuilder (Either ShError [Sh]) ())
-> ShM () -> ListBuilder (Either ShError [Sh]) ()
forall a b. (a -> b) -> a -> b
$ do
            String -> ShM ()
change_dir String
"$BUILDDIR"
            String -> ShM ()
run_cmd String
"mkdir -p \"$BUILDDIR/unpacked\""
            String -> ShM ()
run_cmd String
"find \"$BUILDDIR/sdist\" -maxdepth 1 -type f -name '*.tar.gz' -exec tar -C \"$BUILDDIR/unpacked\" -xzvf {} \\;"

        -- write cabal.project
        String -> ShM () -> ListBuilder (Either ShError [Sh]) ()
step String
"generate cabal.project" (ShM () -> ListBuilder (Either ShError [Sh]) ())
-> ShM () -> ListBuilder (Either ShError [Sh]) ()
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{String
pkgName :: Package -> String
pkgName :: String
pkgName} -> do
                String -> ShM ()
forall (m :: * -> *). MonadSh m => String -> m ()
sh (String -> ShM ()) -> String -> ShM ()
forall a b. (a -> b) -> a -> b
$ String -> String
pkgNameDirVariable' String
pkgName String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"=\"$(find \"$BUILDDIR/unpacked\" -maxdepth 1 -type d -regex '.*/" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
pkgName String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"-[0-9.]*')\""

            String -> ShM ()
run_cmd String
"touch cabal.project"
            String -> ShM ()
run_cmd String
"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 -> String -> String -> 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) String
"cabal.project" (String -> ShM ()) -> String -> ShM ()
forall a b. (a -> b) -> a -> b
$ String
"packages: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
pkgNameDirVariable (Package -> String
pkgName Package
pkg)

            -- per package options
            case PackageScope
cfgErrorMissingMethods of
                PackageScope
PackageScopeNone  -> () -> ShM ()
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{String
pkgName :: String
pkgName :: Package -> String
pkgName,Set CompilerVersion
pkgJobs :: Set CompilerVersion
pkgJobs :: Package -> 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 -> String -> String -> ShM ()
echo_if_to CompilerRange
range String
"cabal.project" (String -> ShM ()) -> String -> ShM ()
forall a b. (a -> b) -> a -> b
$ String
"package " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
pkgName
                    CompilerRange -> String -> String -> ShM ()
echo_if_to CompilerRange
range String
"cabal.project" (String -> ShM ()) -> String -> ShM ()
forall a b. (a -> b) -> a -> b
$ String
"    ghc-options: -Werror=missing-methods"
                PackageScope
PackageScopeAll   -> String -> String -> ShM ()
cat String
"cabal.project" (String -> ShM ()) -> String -> ShM ()
forall a b. (a -> b) -> a -> b
$ [String] -> String
unlines
                    [ String
"package *"
                    , String
"  ghc-options: -Werror=missing-methods"
                    ]

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

            -- 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 -> String -> ShM ()
forall (m :: * -> *). MonadSh m => String -> m ()
sh (String -> ShM ()) -> String -> ShM ()
forall a b. (a -> b) -> a -> b
$ [String] -> String
unwords
                    [ String
"$HCPKG list --simple-output --names-only"
                    , String
"| perl -ne 'for (split /\\s+/) { print \"constraints: $_ installed\\n\" unless /" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
re String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"/; }'"
                    , String
">> cabal.project.local"
                    ]
                  where
                    pns' :: Set String
pns' = (PackageName -> String) -> Set PackageName -> Set String
forall b a. Ord b => (a -> b) -> Set a -> Set b
S.map PackageName -> String
C.unPackageName Set PackageName
pns Set String -> Set String -> Set String
forall a. Ord a => Set a -> Set a -> Set a
`S.union` (Package -> Set String) -> [Package] -> Set String
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap (String -> Set String
forall a. a -> Set a
S.singleton (String -> Set String)
-> (Package -> String) -> Package -> Set String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Package -> String
pkgName) [Package]
pkgs
                    re :: String
re = String
"^(" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
"|" (Set String -> [String]
forall a. Set a -> [a]
S.toList Set String
pns') String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")$"

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

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

            String -> ShM ()
run_cmd String
"cat cabal.project"
            String -> ShM ()
run_cmd String
"cat cabal.project.local"

        -- dump install plan
        String -> ShM () -> ListBuilder (Either ShError [Sh]) ()
step String
"dump install plan" (ShM () -> ListBuilder (Either ShError [Sh]) ())
-> ShM () -> ListBuilder (Either ShError [Sh]) ()
forall a b. (a -> b) -> a -> b
$ do
            String -> ShM ()
run_cmd String
"$CABAL v2-build $ARG_COMPILER $ARG_TESTS $ARG_BENCH --dry-run all"
            String -> ShM ()
run_cmd String
"cabal-plan"

        -- install dependencies
        Bool
-> ListBuilder (Either ShError [Sh]) ()
-> ListBuilder (Either ShError [Sh]) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
cfgInstallDeps (ListBuilder (Either ShError [Sh]) ()
 -> ListBuilder (Either ShError [Sh]) ())
-> ListBuilder (Either ShError [Sh]) ()
-> ListBuilder (Either ShError [Sh]) ()
forall a b. (a -> b) -> a -> b
$ String -> ShM () -> ListBuilder (Either ShError [Sh]) ()
step String
"install dependencies" (ShM () -> ListBuilder (Either ShError [Sh]) ())
-> ShM () -> ListBuilder (Either ShError [Sh]) ()
forall a b. (a -> b) -> a -> b
$ do
            String -> ShM ()
run_cmd String
"$CABAL v2-build $ARG_COMPILER --disable-tests --disable-benchmarks --dependencies-only -j all"
            String -> ShM ()
run_cmd String
"$CABAL v2-build $ARG_COMPILER $ARG_TESTS $ARG_BENCH --dependencies-only -j all"

        Bool
-> ListBuilder (Either ShError [Sh]) ()
-> ListBuilder (Either ShError [Sh]) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (VersionRange -> VersionRange -> Bool
equivVersionRanges VersionRange
C.noVersion VersionRange
cfgNoTestsNoBench) (ListBuilder (Either ShError [Sh]) ()
 -> ListBuilder (Either ShError [Sh]) ())
-> ListBuilder (Either ShError [Sh]) ()
-> ListBuilder (Either ShError [Sh]) ()
forall a b. (a -> b) -> a -> b
$ String -> ShM () -> ListBuilder (Either ShError [Sh]) ()
step String
"build w/o tests" (ShM () -> ListBuilder (Either ShError [Sh]) ())
-> ShM () -> ListBuilder (Either ShError [Sh]) ()
forall a b. (a -> b) -> a -> b
$ do
            String -> ShM ()
run_cmd String
"$CABAL v2-build $ARG_COMPILER --disable-tests --disable-benchmarks all"

        -- build
        String -> ShM () -> ListBuilder (Either ShError [Sh]) ()
step String
"build" (ShM () -> ListBuilder (Either ShError [Sh]) ())
-> ShM () -> ListBuilder (Either ShError [Sh]) ()
forall a b. (a -> b) -> a -> b
$ do
            String -> ShM ()
run_cmd String
"$CABAL v2-build $ARG_COMPILER $ARG_TESTS $ARG_BENCH all"

        -- tests
        String -> ShM () -> ListBuilder (Either ShError [Sh]) ()
step String
"tests" (ShM () -> ListBuilder (Either ShError [Sh]) ())
-> ShM () -> ListBuilder (Either ShError [Sh]) ()
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 -> String -> ShM ()
run_cmd_if CompilerRange
range (String -> ShM ()) -> String -> ShM ()
forall a b. (a -> b) -> a -> b
$ String
"$CABAL v2-test $ARG_COMPILER $ARG_TESTS $ARG_BENCH all" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
testShowDetails

        -- doctest
        Bool
-> ListBuilder (Either ShError [Sh]) ()
-> ListBuilder (Either ShError [Sh]) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
doctestEnabled (ListBuilder (Either ShError [Sh]) ()
 -> ListBuilder (Either ShError [Sh]) ())
-> ListBuilder (Either ShError [Sh]) ()
-> ListBuilder (Either ShError [Sh]) ()
forall a b. (a -> b) -> a -> b
$ String -> ShM () -> ListBuilder (Either ShError [Sh]) ()
step String
"doctest" (ShM () -> ListBuilder (Either ShError [Sh]) ())
-> ShM () -> ListBuilder (Either ShError [Sh]) ()
forall a b. (a -> b) -> a -> b
$ do
            let doctestOptions :: String
doctestOptions = [String] -> String
unwords ([String] -> String) -> [String] -> String
forall a b. (a -> b) -> a -> b
$ DoctestConfig -> [String]
cfgDoctestOptions DoctestConfig
cfgDoctest

            Bool -> ShM () -> ShM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless ([PackageName] -> 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 :: String -> [String]
manglePkgNames String
n
                        | Set Version -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null Set Version
cfgOsx = [String
n]
                        | Bool
otherwise   = [String
n, (Char -> Bool) -> String -> String
forall a. (a -> Bool) -> [a] -> [a]
filter Char -> Bool
notVowel String
n]
                      where
                        notVowel :: Char -> Bool
notVowel Char
c = Char -> String -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
notElem Char
c (String
"aeiou" :: String)
                let filterPkgs :: String
filterPkgs = String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
"|" ([String] -> String) -> [String] -> String
forall a b. (a -> b) -> a -> b
$ (PackageName -> [String]) -> [PackageName] -> [String]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (String -> [String]
manglePkgNames (String -> [String])
-> (PackageName -> String) -> PackageName -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PackageName -> String
C.unPackageName) ([PackageName] -> [String]) -> [PackageName] -> [String]
forall a b. (a -> b) -> a -> b
$ DoctestConfig -> [PackageName]
cfgDoctestFilterEnvPkgs DoctestConfig
cfgDoctest
                String -> ShM ()
run_cmd (String -> ShM ()) -> String -> ShM ()
forall a b. (a -> b) -> a -> b
$ String
"perl -i -e 'while (<ARGV>) { print unless /package-id\\s+(" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
filterPkgs String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")-\\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{String
pkgName :: String
pkgName :: Package -> String
pkgName,GenericPackageDescription
pkgGpd :: Package -> GenericPackageDescription
pkgGpd :: GenericPackageDescription
pkgGpd,Set CompilerVersion
pkgJobs :: Set CompilerVersion
pkgJobs :: Package -> Set CompilerVersion
pkgJobs} ->
                Bool -> ShM () -> ShM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (String -> PackageName
C.mkPackageName String
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
                    [[String]] -> ([String] -> ShM ()) -> ShM ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ (GenericPackageDescription -> [[String]]
doctestArgs GenericPackageDescription
pkgGpd) (([String] -> ShM ()) -> ShM ()) -> ([String] -> ShM ()) -> ShM ()
forall a b. (a -> b) -> a -> b
$ \[String]
args -> do
                        let args' :: String
args' = [String] -> String
unwords [String]
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 ([String] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [String]
args) (ShM () -> ShM ()) -> ShM () -> ShM ()
forall a b. (a -> b) -> a -> b
$ do
                            CompilerRange -> String -> ShM ()
change_dir_if CompilerRange
vr (String -> ShM ()) -> String -> ShM ()
forall a b. (a -> b) -> a -> b
$ String -> String
pkgNameDirVariable String
pkgName
                            CompilerRange -> String -> ShM ()
run_cmd_if CompilerRange
vr (String -> ShM ()) -> String -> ShM ()
forall a b. (a -> b) -> a -> b
$ String
"doctest " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
doctestOptions String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
args'

        -- hlint
        -- TODO

        -- cabal check
        Bool
-> ListBuilder (Either ShError [Sh]) ()
-> ListBuilder (Either ShError [Sh]) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
cfgCheck (ListBuilder (Either ShError [Sh]) ()
 -> ListBuilder (Either ShError [Sh]) ())
-> ListBuilder (Either ShError [Sh]) ()
-> ListBuilder (Either ShError [Sh]) ()
forall a b. (a -> b) -> a -> b
$ String -> ShM () -> ListBuilder (Either ShError [Sh]) ()
step String
"cabal check" (ShM () -> ListBuilder (Either ShError [Sh]) ())
-> ShM () -> ListBuilder (Either ShError [Sh]) ()
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{String
pkgName :: String
pkgName :: Package -> String
pkgName,Set CompilerVersion
pkgJobs :: Set CompilerVersion
pkgJobs :: Package -> Set CompilerVersion
pkgJobs} -> do
                let range :: CompilerRange
range = Set CompilerVersion -> CompilerRange
RangePoints Set CompilerVersion
pkgJobs
                CompilerRange -> String -> ShM ()
change_dir_if CompilerRange
range (String -> ShM ()) -> String -> ShM ()
forall a b. (a -> b) -> a -> b
$ String -> String
pkgNameDirVariable String
pkgName
                CompilerRange -> String -> ShM ()
run_cmd_if CompilerRange
range String
"${CABAL} -vnormal check"
            String -> ShM ()
change_dir String
"$BUILDDIR"

        -- haddock
        Bool
-> ListBuilder (Either ShError [Sh]) ()
-> ListBuilder (Either ShError [Sh]) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Bool
hasLibrary Bool -> Bool -> Bool
&& Bool -> Bool
not (VersionRange -> VersionRange -> Bool
equivVersionRanges VersionRange
C.noVersion VersionRange
cfgHaddock)) (ListBuilder (Either ShError [Sh]) ()
 -> ListBuilder (Either ShError [Sh]) ())
-> ListBuilder (Either ShError [Sh]) ()
-> ListBuilder (Either ShError [Sh]) ()
forall a b. (a -> b) -> a -> b
$ String -> ShM () -> ListBuilder (Either ShError [Sh]) ()
step String
"haddock" (ShM () -> ListBuilder (Either ShError [Sh]) ())
-> ShM () -> ListBuilder (Either ShError [Sh]) ()
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
            CompilerRange -> String -> ShM ()
run_cmd_if CompilerRange
range String
"$CABAL v2-haddock $ARG_COMPILER --with-haddock $HADDOCK $ARG_TESTS $ARG_BENCH all"

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

        -- constraint sets
        Bool
-> ListBuilder (Either ShError [Sh]) ()
-> ListBuilder (Either ShError [Sh]) ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless ([ConstraintSet] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [ConstraintSet]
cfgConstraintSets) (ListBuilder (Either ShError [Sh]) ()
 -> ListBuilder (Either ShError [Sh]) ())
-> ListBuilder (Either ShError [Sh]) ()
-> ListBuilder (Either ShError [Sh]) ()
forall a b. (a -> b) -> a -> b
$ String -> ShM () -> ListBuilder (Either ShError [Sh]) ()
step String
"constraint sets" (ShM () -> ListBuilder (Either ShError [Sh]) ())
-> ShM () -> ListBuilder (Either ShError [Sh]) ()
forall a b. (a -> b) -> a -> b
$ do
            String -> ShM ()
run_cmd String
"rm -f cabal.project.local"

            [ConstraintSet] -> (ConstraintSet -> ShM ()) -> ShM ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
t a -> (a -> f b) -> f ()
for_ [ConstraintSet]
cfgConstraintSets ((ConstraintSet -> ShM ()) -> ShM ())
-> (ConstraintSet -> ShM ()) -> ShM ()
forall a b. (a -> b) -> a -> b
$ \ConstraintSet
cs -> do
                let name :: String
name            = ConstraintSet -> String
csName ConstraintSet
cs
                let run_cmd_cs :: String -> ShM ()
run_cmd_cs      = CompilerRange -> String -> ShM ()
run_cmd_if (VersionRange -> CompilerRange
Range (ConstraintSet -> VersionRange
csGhcVersions ConstraintSet
cs))
                let run_cmd_cs' :: CompilerRange -> String -> ShM ()
run_cmd_cs' CompilerRange
r   = CompilerRange -> String -> ShM ()
run_cmd_if (VersionRange -> CompilerRange
Range (ConstraintSet -> VersionRange
csGhcVersions ConstraintSet
cs) CompilerRange -> CompilerRange -> CompilerRange
forall a. Lattice a => a -> a -> a
/\ CompilerRange
r)
                let testFlag :: String
testFlag        = if ConstraintSet -> Bool
csTests ConstraintSet
cs then String
"--enable-tests" else String
"--disable-tests"
                let benchFlag :: String
benchFlag       = if ConstraintSet -> Bool
csBenchmarks ConstraintSet
cs then String
"--enable-benchmarks" else String
"--disable-benchmarks"
                let constraintFlags :: [String]
constraintFlags = (String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (\String
x ->  String
"--constraint='" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
x String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"'") (ConstraintSet -> [String]
csConstraints ConstraintSet
cs)
                let allFlags :: String
allFlags        = [String] -> String
unwords (String
testFlag String -> [String] -> [String]
forall a. a -> [a] -> [a]
: String
benchFlag String -> [String] -> [String]
forall a. a -> [a] -> [a]
: [String]
constraintFlags)

                String -> ShM ()
put_info (String -> ShM ()) -> String -> ShM ()
forall a b. (a -> b) -> a -> b
$ String
"constraint set " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
name
                String -> ShM ()
run_cmd_cs (String -> ShM ()) -> String -> ShM ()
forall a b. (a -> b) -> a -> b
$ String
"$CABAL v2-build $ARG_COMPILER " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
allFlags String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" all"
                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 -> String -> ShM ()
run_cmd_cs' CompilerRange
hasTests (String -> ShM ()) -> String -> ShM ()
forall a b. (a -> b) -> a -> b
$ String
"$CABAL v2-test $ARG_COMPILER " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
allFlags String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" all"
                Bool -> ShM () -> ShM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Bool
hasLibrary Bool -> Bool -> Bool
&& ConstraintSet -> Bool
csHaddock ConstraintSet
cs) (ShM () -> ShM ()) -> ShM () -> ShM ()
forall a b. (a -> b) -> a -> b
$
                    String -> ShM ()
run_cmd_cs (String -> ShM ()) -> String -> ShM ()
forall a b. (a -> b) -> a -> b
$ String
"$CABAL v2-haddock $ARG_COMPILER " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
withHaddock String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
allFlags String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" all"

    Z -> Either ShError Z
forall (m :: * -> *) a. Monad m => a -> m a
return Z
defaultZ
        { zJobs :: [String]
zJobs =
            [ Version -> String
forall a. Pretty a => a -> String
prettyShow Version
v
            | GHC Version
v <- [CompilerVersion] -> [CompilerVersion]
forall a. [a] -> [a]
reverse ([CompilerVersion] -> [CompilerVersion])
-> [CompilerVersion] -> [CompilerVersion]
forall a b. (a -> b) -> a -> b
$ Set CompilerVersion -> [CompilerVersion]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList Set CompilerVersion
versions
            ]
        , zBlocks :: [String]
zBlocks = [String]
blocks
        , zApt :: [String]
zApt = Set String -> [String]
forall a. Set a -> [a]
S.toList Set String
cfgApt
        , zTestsCond :: String
zTestsCond = Set CompilerVersion -> CompilerRange -> String
compilerVersionArithPredicate Set CompilerVersion
versions (CompilerRange -> String) -> CompilerRange -> String
forall a b. (a -> b) -> a -> b
$ VersionRange -> CompilerRange
Range VersionRange
cfgTests
        , zBenchCond :: String
zBenchCond = Set CompilerVersion -> CompilerRange -> String
compilerVersionArithPredicate Set CompilerVersion
versions (CompilerRange -> String) -> CompilerRange -> String
forall a b. (a -> b) -> a -> b
$ VersionRange -> CompilerRange
Range VersionRange
cfgBenchmarks
        }
  where
    Auxiliary {Bool
String
[PrettyField ()]
[URI]
[Package]
CompilerRange
testShowDetails :: Auxiliary -> String
extraCabalProjectFields :: Auxiliary -> [PrettyField ()]
hasLibrary :: Auxiliary -> Bool
hasTests :: Auxiliary -> CompilerRange
docspecEnabled :: Auxiliary -> Bool
doctestEnabled :: Auxiliary -> Bool
projectName :: Auxiliary -> String
uris :: Auxiliary -> [URI]
pkgs :: Auxiliary -> [Package]
docspecEnabled :: Bool
projectName :: String
uris :: [URI]
hasLibrary :: Bool
testShowDetails :: String
hasTests :: CompilerRange
extraCabalProjectFields :: [PrettyField ()]
pkgs :: [Package]
doctestEnabled :: Bool
..} = Config -> Project URI Void Package -> JobVersions -> Auxiliary
auxiliary Config
config Project URI Void Package
prj JobVersions
jobs

    -- TODO: this can be smart and do nothing is there are only comments in [Sh]
    step :: String -> ShM () -> ListBuilder (Either ShError [Sh]) ()
    step :: String -> ShM () -> ListBuilder (Either ShError [Sh]) ()
step String
name ShM ()
action = Either ShError [Sh] -> ListBuilder (Either ShError [Sh]) ()
forall x. x -> ListBuilder x ()
item (Either ShError [Sh] -> ListBuilder (Either ShError [Sh]) ())
-> Either ShError [Sh] -> ListBuilder (Either ShError [Sh]) ()
forall a b. (a -> b) -> a -> b
$ ShM () -> Either ShError [Sh]
forall e (m :: * -> *).
(MonadErr e m, FromShError e) =>
ShM () -> m [Sh]
runSh (ShM () -> Either ShError [Sh]) -> ShM () -> Either ShError [Sh]
forall a b. (a -> b) -> a -> b
$ do
        String -> ShM ()
forall (m :: * -> *). MonadSh m => String -> m ()
comment String
name
        String -> ShM ()
put_info String
name
        ShM ()
action

    put_info :: String -> ShM ()
    put_info :: String -> ShM ()
put_info String
s = String -> ShM ()
forall (m :: * -> *). MonadSh m => String -> m ()
sh (String -> ShM ()) -> String -> ShM ()
forall a b. (a -> b) -> a -> b
$ String
"put_info " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
forall a. Show a => a -> String
show String
s

    change_dir :: String -> ShM ()
    change_dir :: String -> ShM ()
change_dir String
dir = String -> ShM ()
forall (m :: * -> *). MonadSh m => String -> m ()
sh (String -> ShM ()) -> String -> ShM ()
forall a b. (a -> b) -> a -> b
$ String
"change_dir " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> String
forall a. Show a => a -> String
show String
dir

    change_dir_if :: CompilerRange -> String -> ShM ()
    change_dir_if :: CompilerRange -> String -> ShM ()
change_dir_if CompilerRange
vr String
dir
        | (CompilerVersion -> Bool) -> Set CompilerVersion -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (CompilerVersion -> CompilerRange -> Bool
`compilerWithinRange` CompilerRange
vr) Set CompilerVersion
versions       = String -> ShM ()
change_dir String
dir
        | 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
vr) Set CompilerVersion
versions = () -> ShM ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
        | Bool
otherwise = String -> ShM ()
forall (m :: * -> *). MonadSh m => String -> m ()
sh (String -> ShM ()) -> String -> ShM ()
forall a b. (a -> b) -> a -> b
$ [String] -> String
unwords
            [ String
"change_dir_if"
            , Set CompilerVersion -> CompilerRange -> String
compilerVersionArithPredicate Set CompilerVersion
versions CompilerRange
vr
            , String
dir
            ]

    run_cmd :: String -> ShM ()
    run_cmd :: String -> ShM ()
run_cmd String
cmd = String -> ShM ()
forall (m :: * -> *). MonadSh m => String -> m ()
sh (String -> ShM ()) -> String -> ShM ()
forall a b. (a -> b) -> a -> b
$ [String] -> String
unwords
        [ String
"run_cmd"
        , String
cmd
        ]

    run_cmd_if :: CompilerRange -> String -> ShM ()
    run_cmd_if :: CompilerRange -> String -> ShM ()
run_cmd_if CompilerRange
vr String
cmd
        | (CompilerVersion -> Bool) -> Set CompilerVersion -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (CompilerVersion -> CompilerRange -> Bool
`compilerWithinRange` CompilerRange
vr) Set CompilerVersion
versions       = String -> ShM ()
run_cmd String
cmd
        | 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
vr) Set CompilerVersion
versions = () -> ShM ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
        | Bool
otherwise = String -> ShM ()
forall (m :: * -> *). MonadSh m => String -> m ()
sh (String -> ShM ()) -> String -> ShM ()
forall a b. (a -> b) -> a -> b
$ [String] -> String
unwords
            [ String
"run_cmd_if"
            , Set CompilerVersion -> CompilerRange -> String
compilerVersionArithPredicate Set CompilerVersion
versions CompilerRange
vr
            , String
cmd
            ]

    echo_if_to :: CompilerRange -> FilePath -> String -> ShM ()
    echo_if_to :: CompilerRange -> String -> String -> ShM ()
echo_if_to CompilerRange
vr String
path String
contents
        | (CompilerVersion -> Bool) -> Set CompilerVersion -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (CompilerVersion -> CompilerRange -> Bool
`compilerWithinRange` CompilerRange
vr) Set CompilerVersion
versions = String -> ShM ()
forall (m :: * -> *). MonadSh m => String -> m ()
sh (String -> ShM ()) -> String -> ShM ()
forall a b. (a -> b) -> a -> b
$ [String] -> String
unwords
            [ String
"echo_to"
            , String
path
            , String -> String
forall a. Show a => a -> String
show String
contents
            ]
        | 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
vr) Set CompilerVersion
versions = () -> ShM ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
        | Bool
otherwise = String -> ShM ()
forall (m :: * -> *). MonadSh m => String -> m ()
sh (String -> ShM ()) -> String -> ShM ()
forall a b. (a -> b) -> a -> b
$ [String] -> String
unwords
            [ String
"echo_if_to"
            , Set CompilerVersion -> CompilerRange -> String
compilerVersionArithPredicate Set CompilerVersion
versions CompilerRange
vr
            , String
path
            , String -> String
forall a. Show a => a -> String
show String
contents
            ]

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

shsToList :: [Sh] -> String
shsToList :: [Sh] -> String
shsToList = [String] -> String
unlines ([String] -> String) -> ([Sh] -> [String]) -> [Sh] -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Sh -> String) -> [Sh] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map Sh -> String
f where
    f :: Sh -> String
f (Sh String
x)      = String
x
    f (Comment String
c) = String
"# " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
c

cat :: FilePath -> String -> ShM ()
cat :: String -> String -> ShM ()
cat String
path String
contents = String -> ShM ()
forall (m :: * -> *). MonadSh m => String -> m ()
sh (String -> ShM ()) -> String -> ShM ()
forall a b. (a -> b) -> a -> b
$ [String] -> String
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
    [ String
"cat >> " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
path String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" <<EOF\n"
    , String
contents
    , String
"EOF"
    ]