{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE RecursiveDo #-}
{-# LANGUAGE RecordWildCards #-}
module HIE.Bios.Cradle (
findCradle
, loadCradle
, loadImplicitCradle
, yamlConfig
, defaultCradle
, isCabalCradle
, isStackCradle
, isDirectCradle
, isBiosCradle
, isNoneCradle
, isMultiCradle
, isDefaultCradle
, isOtherCradle
, getCradle
, readProcessWithOutputs
, readProcessWithCwd
, makeCradleResult
, CradleProjectConfig(..)
,
) where
import Control.Applicative ((<|>), optional)
import Data.Bifunctor (first)
import Control.DeepSeq
import Control.Exception (handleJust)
import qualified Data.Yaml as Yaml
import Data.Void
import Data.Char (isSpace)
import System.Exit
import System.Directory hiding (findFile)
import Colog.Core (LogAction (..), WithSeverity (..), Severity (..), (<&))
import Control.Monad
import Control.Monad.Extra (unlessM)
import Control.Monad.Trans.Cont
import Control.Monad.Trans.Maybe
import Control.Monad.IO.Class
import Data.Conduit.Process
import qualified Data.Conduit.Combinators as C
import qualified Data.Conduit as C
import qualified Data.Conduit.Text as C
import qualified Data.HashMap.Strict as Map
import Data.Maybe (fromMaybe, maybeToList)
import Data.List
import Data.List.Extra (trimEnd)
import Data.Ord (Down(..))
import qualified Data.Text as T
import System.Environment
import System.FilePath
import System.PosixCompat.Files
import System.Info.Extra (isWindows)
import System.IO (hClose, hGetContents, hSetBuffering, BufferMode(LineBuffering), withFile, IOMode(..))
import System.IO.Error (isPermissionError)
import System.IO.Temp
import HIE.Bios.Config
import HIE.Bios.Environment (getCacheDir)
import HIE.Bios.Types hiding (ActionName(..))
import HIE.Bios.Wrappers
import qualified HIE.Bios.Types as Types
import qualified HIE.Bios.Ghc.Gap as Gap
import GHC.Fingerprint (fingerprintString)
import GHC.ResponseFile (escapeArgs)
import Data.Version
import System.IO.Unsafe (unsafeInterleaveIO)
import Text.ParserCombinators.ReadP (readP_to_S)
findCradle :: FilePath -> IO (Maybe FilePath)
findCradle :: String -> IO (Maybe String)
findCradle String
wfile = do
let wdir :: String
wdir = String -> String
takeDirectory String
wfile
MaybeT IO String -> IO (Maybe String)
forall (m :: * -> *) a. MaybeT m a -> m (Maybe a)
runMaybeT (String -> MaybeT IO String
yamlConfig String
wdir)
loadCradle :: LogAction IO (WithSeverity Log) -> FilePath -> IO (Cradle Void)
loadCradle :: LogAction IO (WithSeverity Log) -> String -> IO (Cradle Void)
loadCradle LogAction IO (WithSeverity Log)
l = LogAction IO (WithSeverity Log)
-> (Void -> CradleAction Void) -> String -> IO (Cradle Void)
forall b a.
(FromJSON b, Show a) =>
LogAction IO (WithSeverity Log)
-> (b -> CradleAction a) -> String -> IO (Cradle a)
loadCradleWithOpts LogAction IO (WithSeverity Log)
l Void -> CradleAction Void
forall a. Void -> a
absurd
loadImplicitCradle :: Show a => LogAction IO (WithSeverity Log) -> FilePath -> IO (Cradle a)
loadImplicitCradle :: forall a.
Show a =>
LogAction IO (WithSeverity Log) -> String -> IO (Cradle a)
loadImplicitCradle LogAction IO (WithSeverity Log)
l String
wfile = do
let wdir :: String
wdir = String -> String
takeDirectory String
wfile
Maybe (CradleConfig Void, String)
cfg <- MaybeT IO (CradleConfig Void, String)
-> IO (Maybe (CradleConfig Void, String))
forall (m :: * -> *) a. MaybeT m a -> m (Maybe a)
runMaybeT (String -> MaybeT IO (CradleConfig Void, String)
forall a. String -> MaybeT IO (CradleConfig a, String)
implicitConfig String
wdir)
case Maybe (CradleConfig Void, String)
cfg of
Just (CradleConfig Void, String)
bc -> LogAction IO (WithSeverity Log)
-> (Void -> CradleAction a)
-> (CradleConfig Void, String)
-> IO (Cradle a)
forall a b.
Show a =>
LogAction IO (WithSeverity Log)
-> (b -> CradleAction a)
-> (CradleConfig b, String)
-> IO (Cradle a)
getCradle LogAction IO (WithSeverity Log)
l Void -> CradleAction a
forall a. Void -> a
absurd (CradleConfig Void, String)
bc
Maybe (CradleConfig Void, String)
Nothing -> Cradle a -> IO (Cradle a)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Cradle a -> IO (Cradle a)) -> Cradle a -> IO (Cradle a)
forall a b. (a -> b) -> a -> b
$ LogAction IO (WithSeverity Log) -> String -> Cradle a
forall a. LogAction IO (WithSeverity Log) -> String -> Cradle a
defaultCradle LogAction IO (WithSeverity Log)
l String
wdir
loadCradleWithOpts :: (Yaml.FromJSON b, Show a) => LogAction IO (WithSeverity Log) -> (b -> CradleAction a) -> FilePath -> IO (Cradle a)
loadCradleWithOpts :: forall b a.
(FromJSON b, Show a) =>
LogAction IO (WithSeverity Log)
-> (b -> CradleAction a) -> String -> IO (Cradle a)
loadCradleWithOpts LogAction IO (WithSeverity Log)
l b -> CradleAction a
buildCustomCradle String
wfile = do
CradleConfig b
cradleConfig <- String -> IO (CradleConfig b)
forall b. FromJSON b => String -> IO (CradleConfig b)
readCradleConfig String
wfile
LogAction IO (WithSeverity Log)
-> (b -> CradleAction a)
-> (CradleConfig b, String)
-> IO (Cradle a)
forall a b.
Show a =>
LogAction IO (WithSeverity Log)
-> (b -> CradleAction a)
-> (CradleConfig b, String)
-> IO (Cradle a)
getCradle LogAction IO (WithSeverity Log)
l b -> CradleAction a
buildCustomCradle (CradleConfig b
cradleConfig, String -> String
takeDirectory String
wfile)
getCradle :: Show a => LogAction IO (WithSeverity Log) -> (b -> CradleAction a) -> (CradleConfig b, FilePath) -> IO (Cradle a)
getCradle :: forall a b.
Show a =>
LogAction IO (WithSeverity Log)
-> (b -> CradleAction a)
-> (CradleConfig b, String)
-> IO (Cradle a)
getCradle LogAction IO (WithSeverity Log)
l b -> CradleAction a
buildCustomCradle (CradleConfig b
cc, String
wdir) = do
[ResolvedCradle b]
rcs <- String -> [ResolvedCradle b] -> IO [ResolvedCradle b]
forall a. String -> [ResolvedCradle a] -> IO [ResolvedCradle a]
canonicalizeResolvedCradles String
wdir [ResolvedCradle b]
cs
LogAction IO (WithSeverity Log)
-> (b -> CradleAction a)
-> String
-> [ResolvedCradle b]
-> IO (Cradle a)
forall a b.
Show a =>
LogAction IO (WithSeverity Log)
-> (b -> CradleAction a)
-> String
-> [ResolvedCradle b]
-> IO (Cradle a)
resolvedCradlesToCradle LogAction IO (WithSeverity Log)
l b -> CradleAction a
buildCustomCradle String
wdir [ResolvedCradle b]
rcs
where
cs :: [ResolvedCradle b]
cs = String -> CradleConfig b -> [ResolvedCradle b]
forall a. String -> CradleConfig a -> [ResolvedCradle a]
resolveCradleTree String
wdir CradleConfig b
cc
data ConcreteCradle a
= ConcreteCabal CabalType
| ConcreteStack StackType
| ConcreteBios Callable (Maybe Callable) (Maybe FilePath)
| ConcreteDirect [String]
| ConcreteNone
| ConcreteOther a
deriving Int -> ConcreteCradle a -> String -> String
[ConcreteCradle a] -> String -> String
ConcreteCradle a -> String
(Int -> ConcreteCradle a -> String -> String)
-> (ConcreteCradle a -> String)
-> ([ConcreteCradle a] -> String -> String)
-> Show (ConcreteCradle a)
forall a. Show a => Int -> ConcreteCradle a -> String -> String
forall a. Show a => [ConcreteCradle a] -> String -> String
forall a. Show a => ConcreteCradle a -> String
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
$cshowsPrec :: forall a. Show a => Int -> ConcreteCradle a -> String -> String
showsPrec :: Int -> ConcreteCradle a -> String -> String
$cshow :: forall a. Show a => ConcreteCradle a -> String
show :: ConcreteCradle a -> String
$cshowList :: forall a. Show a => [ConcreteCradle a] -> String -> String
showList :: [ConcreteCradle a] -> String -> String
Show
data ResolvedCradle a
= ResolvedCradle
{ forall a. ResolvedCradle a -> String
prefix :: FilePath
, forall a. ResolvedCradle a -> [String]
cradleDeps :: [FilePath]
, forall a. ResolvedCradle a -> ConcreteCradle a
concreteCradle :: ConcreteCradle a
} deriving Int -> ResolvedCradle a -> String -> String
[ResolvedCradle a] -> String -> String
ResolvedCradle a -> String
(Int -> ResolvedCradle a -> String -> String)
-> (ResolvedCradle a -> String)
-> ([ResolvedCradle a] -> String -> String)
-> Show (ResolvedCradle a)
forall a. Show a => Int -> ResolvedCradle a -> String -> String
forall a. Show a => [ResolvedCradle a] -> String -> String
forall a. Show a => ResolvedCradle a -> String
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
$cshowsPrec :: forall a. Show a => Int -> ResolvedCradle a -> String -> String
showsPrec :: Int -> ResolvedCradle a -> String -> String
$cshow :: forall a. Show a => ResolvedCradle a -> String
show :: ResolvedCradle a -> String
$cshowList :: forall a. Show a => [ResolvedCradle a] -> String -> String
showList :: [ResolvedCradle a] -> String -> String
Show
data ResolvedCradles a
= ResolvedCradles
{ forall a. ResolvedCradles a -> String
cradleRoot :: FilePath
, forall a. ResolvedCradles a -> [ResolvedCradle a]
resolvedCradles :: [ResolvedCradle a]
, forall a. ResolvedCradles a -> ProgramVersions
cradleProgramVersions :: ProgramVersions
}
data ProgramVersions =
ProgramVersions { ProgramVersions -> Maybe Version
cabalVersion :: Maybe Version
, ProgramVersions -> Maybe Version
stackVersion :: Maybe Version
, ProgramVersions -> Maybe Version
ghcVersion :: Maybe Version
}
makeVersions :: LogAction IO (WithSeverity Log) -> FilePath -> ([String] -> IO (CradleLoadResult String)) -> IO ProgramVersions
makeVersions :: LogAction IO (WithSeverity Log)
-> String
-> ([String] -> IO (CradleLoadResult String))
-> IO ProgramVersions
makeVersions LogAction IO (WithSeverity Log)
l String
wdir [String] -> IO (CradleLoadResult String)
ghc = do
Maybe Version
cabalVersion <- IO (Maybe Version) -> IO (Maybe Version)
forall a. IO a -> IO a
unsafeInterleaveIO (LogAction IO (WithSeverity Log) -> String -> IO (Maybe Version)
getCabalVersion LogAction IO (WithSeverity Log)
l String
wdir)
Maybe Version
stackVersion <- IO (Maybe Version) -> IO (Maybe Version)
forall a. IO a -> IO a
unsafeInterleaveIO (LogAction IO (WithSeverity Log) -> String -> IO (Maybe Version)
getStackVersion LogAction IO (WithSeverity Log)
l String
wdir)
Maybe Version
ghcVersion <- IO (Maybe Version) -> IO (Maybe Version)
forall a. IO a -> IO a
unsafeInterleaveIO (([String] -> IO (CradleLoadResult String)) -> IO (Maybe Version)
getGhcVersion [String] -> IO (CradleLoadResult String)
ghc)
ProgramVersions -> IO ProgramVersions
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ProgramVersions{Maybe Version
cabalVersion :: Maybe Version
stackVersion :: Maybe Version
ghcVersion :: Maybe Version
cabalVersion :: Maybe Version
stackVersion :: Maybe Version
ghcVersion :: Maybe Version
..}
getCabalVersion :: LogAction IO (WithSeverity Log) -> FilePath -> IO (Maybe Version)
getCabalVersion :: LogAction IO (WithSeverity Log) -> String -> IO (Maybe Version)
getCabalVersion LogAction IO (WithSeverity Log)
l String
wdir = do
CradleLoadResult String
res <- LogAction IO (WithSeverity Log)
-> String
-> String
-> [String]
-> String
-> IO (CradleLoadResult String)
readProcessWithCwd LogAction IO (WithSeverity Log)
l String
wdir String
"cabal" [String
"--numeric-version"] String
""
case CradleLoadResult String
res of
CradleSuccess String
stdo ->
Maybe Version -> IO (Maybe Version)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe Version -> IO (Maybe Version))
-> Maybe Version -> IO (Maybe Version)
forall a b. (a -> b) -> a -> b
$ String -> Maybe Version
versionMaybe String
stdo
CradleLoadResult String
_ -> Maybe Version -> IO (Maybe Version)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe Version
forall a. Maybe a
Nothing
getStackVersion :: LogAction IO (WithSeverity Log) -> FilePath -> IO (Maybe Version)
getStackVersion :: LogAction IO (WithSeverity Log) -> String -> IO (Maybe Version)
getStackVersion LogAction IO (WithSeverity Log)
l String
wdir = do
CradleLoadResult String
res <- LogAction IO (WithSeverity Log)
-> String
-> String
-> [String]
-> String
-> IO (CradleLoadResult String)
readProcessWithCwd LogAction IO (WithSeverity Log)
l String
wdir String
"stack" [String
"--numeric-version"] String
""
case CradleLoadResult String
res of
CradleSuccess String
stdo ->
Maybe Version -> IO (Maybe Version)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe Version -> IO (Maybe Version))
-> Maybe Version -> IO (Maybe Version)
forall a b. (a -> b) -> a -> b
$ String -> Maybe Version
versionMaybe String
stdo
CradleLoadResult String
_ -> Maybe Version -> IO (Maybe Version)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe Version
forall a. Maybe a
Nothing
getGhcVersion :: ([String] -> IO (CradleLoadResult String)) -> IO (Maybe Version)
getGhcVersion :: ([String] -> IO (CradleLoadResult String)) -> IO (Maybe Version)
getGhcVersion [String] -> IO (CradleLoadResult String)
ghc = do
CradleLoadResult String
res <- [String] -> IO (CradleLoadResult String)
ghc [String
"--numeric-version"]
case CradleLoadResult String
res of
CradleSuccess String
stdo ->
Maybe Version -> IO (Maybe Version)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe Version -> IO (Maybe Version))
-> Maybe Version -> IO (Maybe Version)
forall a b. (a -> b) -> a -> b
$ String -> Maybe Version
versionMaybe String
stdo
CradleLoadResult String
_ -> Maybe Version -> IO (Maybe Version)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe Version
forall a. Maybe a
Nothing
versionMaybe :: String -> Maybe Version
versionMaybe :: String -> Maybe Version
versionMaybe String
xs = case [(Version, String)] -> [(Version, String)]
forall a. [a] -> [a]
reverse ([(Version, String)] -> [(Version, String)])
-> [(Version, String)] -> [(Version, String)]
forall a b. (a -> b) -> a -> b
$ ReadP Version -> ReadS Version
forall a. ReadP a -> ReadS a
readP_to_S ReadP Version
parseVersion String
xs of
[] -> Maybe Version
forall a. Maybe a
Nothing
((Version, String)
x:[(Version, String)]
_) -> Version -> Maybe Version
forall a. a -> Maybe a
Just ((Version, String) -> Version
forall a b. (a, b) -> a
fst (Version, String)
x)
addActionDeps :: [FilePath] -> CradleLoadResult ComponentOptions -> CradleLoadResult ComponentOptions
addActionDeps :: [String]
-> CradleLoadResult ComponentOptions
-> CradleLoadResult ComponentOptions
addActionDeps [String]
deps =
CradleLoadResult ComponentOptions
-> (CradleError -> CradleLoadResult ComponentOptions)
-> (ComponentOptions -> CradleLoadResult ComponentOptions)
-> CradleLoadResult ComponentOptions
-> CradleLoadResult ComponentOptions
forall c r.
c -> (CradleError -> c) -> (r -> c) -> CradleLoadResult r -> c
cradleLoadResult
CradleLoadResult ComponentOptions
forall r. CradleLoadResult r
CradleNone
(\CradleError
err -> CradleError -> CradleLoadResult ComponentOptions
forall r. CradleError -> CradleLoadResult r
CradleFail (CradleError
err { cradleErrorDependencies :: [String]
cradleErrorDependencies = CradleError -> [String]
cradleErrorDependencies CradleError
err [String] -> [String] -> [String]
forall a. Eq a => [a] -> [a] -> [a]
`union` [String]
deps }))
(\(ComponentOptions [String]
os' String
dir [String]
ds) -> ComponentOptions -> CradleLoadResult ComponentOptions
forall r. r -> CradleLoadResult r
CradleSuccess ([String] -> String -> [String] -> ComponentOptions
ComponentOptions [String]
os' String
dir ([String]
ds [String] -> [String] -> [String]
forall a. Eq a => [a] -> [a] -> [a]
`union` [String]
deps)))
resolvedCradlesToCradle :: Show a => LogAction IO (WithSeverity Log) -> (b -> CradleAction a) -> FilePath -> [ResolvedCradle b] -> IO (Cradle a)
resolvedCradlesToCradle :: forall a b.
Show a =>
LogAction IO (WithSeverity Log)
-> (b -> CradleAction a)
-> String
-> [ResolvedCradle b]
-> IO (Cradle a)
resolvedCradlesToCradle LogAction IO (WithSeverity Log)
logger b -> CradleAction a
buildCustomCradle String
root [ResolvedCradle b]
cs = mdo
let run_ghc_cmd :: [String] -> IO (CradleLoadResult String)
run_ghc_cmd [String]
args =
case (CradleAction a -> Bool) -> [CradleAction a] -> [CradleAction a]
forall a. (a -> Bool) -> [a] -> [a]
filter (ActionName a -> Bool
forall {a}. ActionName a -> Bool
notNoneType (ActionName a -> Bool)
-> (CradleAction a -> ActionName a) -> CradleAction a -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CradleAction a -> ActionName a
forall a. CradleAction a -> ActionName a
actionName) ([CradleAction a] -> [CradleAction a])
-> [CradleAction a] -> [CradleAction a]
forall a b. (a -> b) -> a -> b
$ ((ResolvedCradle b, CradleAction a) -> CradleAction a)
-> [(ResolvedCradle b, CradleAction a)] -> [CradleAction a]
forall a b. (a -> b) -> [a] -> [b]
map (ResolvedCradle b, CradleAction a) -> CradleAction a
forall a b. (a, b) -> b
snd [(ResolvedCradle b, CradleAction a)]
cradleActions of
[] -> CradleLoadResult String -> IO (CradleLoadResult String)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return CradleLoadResult String
forall r. CradleLoadResult r
CradleNone
(CradleAction a
act:[CradleAction a]
_) ->
CradleAction a -> [String] -> IO (CradleLoadResult String)
forall a.
CradleAction a -> [String] -> IO (CradleLoadResult String)
runGhcCmd
CradleAction a
act
[String]
args
ProgramVersions
versions <- LogAction IO (WithSeverity Log)
-> String
-> ([String] -> IO (CradleLoadResult String))
-> IO ProgramVersions
makeVersions LogAction IO (WithSeverity Log)
logger String
root [String] -> IO (CradleLoadResult String)
run_ghc_cmd
let rcs :: ResolvedCradles b
rcs = String
-> [ResolvedCradle b] -> ProgramVersions -> ResolvedCradles b
forall a.
String
-> [ResolvedCradle a] -> ProgramVersions -> ResolvedCradles a
ResolvedCradles String
root [ResolvedCradle b]
cs ProgramVersions
versions
cradleActions :: [(ResolvedCradle b, CradleAction a)]
cradleActions = [ (ResolvedCradle b
c, LogAction IO (WithSeverity Log)
-> (b -> CradleAction a)
-> ResolvedCradles b
-> String
-> ResolvedCradle b
-> CradleAction a
forall b a.
LogAction IO (WithSeverity Log)
-> (b -> CradleAction a)
-> ResolvedCradles b
-> String
-> ResolvedCradle b
-> CradleAction a
resolveCradleAction LogAction IO (WithSeverity Log)
logger b -> CradleAction a
buildCustomCradle ResolvedCradles b
rcs String
root ResolvedCradle b
c) | ResolvedCradle b
c <- [ResolvedCradle b]
cs ]
err_msg :: String -> [String]
err_msg String
fp
= [String
"Multi Cradle: No prefixes matched"
, String
"pwd: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
root
, String
"filepath: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
fp
, String
"prefixes:"
] [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [(String, ActionName a) -> String
forall a. Show a => a -> String
show (ResolvedCradle b -> String
forall a. ResolvedCradle a -> String
prefix ResolvedCradle b
pf, CradleAction a -> ActionName a
forall a. CradleAction a -> ActionName a
actionName CradleAction a
cc) | (ResolvedCradle b
pf, CradleAction a
cc) <- [(ResolvedCradle b, CradleAction a)]
cradleActions]
Cradle a -> IO (Cradle a)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Cradle a -> IO (Cradle a)) -> Cradle a -> IO (Cradle a)
forall a b. (a -> b) -> a -> b
$ Cradle
{ cradleRootDir :: String
cradleRootDir = String
root
, cradleLogger :: LogAction IO (WithSeverity Log)
cradleLogger = LogAction IO (WithSeverity Log)
logger
, cradleOptsProg :: CradleAction a
cradleOptsProg = CradleAction
{ actionName :: ActionName a
actionName = ActionName a
forall {a}. ActionName a
multiActionName
, runCradle :: String -> [String] -> IO (CradleLoadResult ComponentOptions)
runCradle = \String
fp [String]
prev -> do
String
absfp <- String -> IO String
makeAbsolute String
fp
case ((ResolvedCradle b, CradleAction a) -> String)
-> String
-> [(ResolvedCradle b, CradleAction a)]
-> Maybe (ResolvedCradle b, CradleAction a)
forall a. (a -> String) -> String -> [a] -> Maybe a
selectCradle (ResolvedCradle b -> String
forall a. ResolvedCradle a -> String
prefix (ResolvedCradle b -> String)
-> ((ResolvedCradle b, CradleAction a) -> ResolvedCradle b)
-> (ResolvedCradle b, CradleAction a)
-> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ResolvedCradle b, CradleAction a) -> ResolvedCradle b
forall a b. (a, b) -> a
fst) String
absfp [(ResolvedCradle b, CradleAction a)]
cradleActions of
Just (ResolvedCradle b
rc, CradleAction a
act) -> do
[String]
-> CradleLoadResult ComponentOptions
-> CradleLoadResult ComponentOptions
addActionDeps (ResolvedCradle b -> [String]
forall a. ResolvedCradle a -> [String]
cradleDeps ResolvedCradle b
rc) (CradleLoadResult ComponentOptions
-> CradleLoadResult ComponentOptions)
-> IO (CradleLoadResult ComponentOptions)
-> IO (CradleLoadResult ComponentOptions)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> CradleAction a
-> String -> [String] -> IO (CradleLoadResult ComponentOptions)
forall a.
CradleAction a
-> String -> [String] -> IO (CradleLoadResult ComponentOptions)
runCradle CradleAction a
act String
fp [String]
prev
Maybe (ResolvedCradle b, CradleAction a)
Nothing -> CradleLoadResult ComponentOptions
-> IO (CradleLoadResult ComponentOptions)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (CradleLoadResult ComponentOptions
-> IO (CradleLoadResult ComponentOptions))
-> CradleLoadResult ComponentOptions
-> IO (CradleLoadResult ComponentOptions)
forall a b. (a -> b) -> a -> b
$ CradleError -> CradleLoadResult ComponentOptions
forall r. CradleError -> CradleLoadResult r
CradleFail (CradleError -> CradleLoadResult ComponentOptions)
-> CradleError -> CradleLoadResult ComponentOptions
forall a b. (a -> b) -> a -> b
$ [String] -> ExitCode -> [String] -> CradleError
CradleError [] ExitCode
ExitSuccess (String -> [String]
err_msg String
fp)
, runGhcCmd :: [String] -> IO (CradleLoadResult String)
runGhcCmd = [String] -> IO (CradleLoadResult String)
run_ghc_cmd
}
}
where
multiActionName :: ActionName a
multiActionName
| (ResolvedCradle b -> Bool) -> [ResolvedCradle b] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (\ResolvedCradle b
c -> ResolvedCradle b -> Bool
forall {a}. ResolvedCradle a -> Bool
isStackCradleConfig ResolvedCradle b
c Bool -> Bool -> Bool
|| ResolvedCradle b -> Bool
forall {a}. ResolvedCradle a -> Bool
isNoneCradleConfig ResolvedCradle b
c) [ResolvedCradle b]
cs
= ActionName a
forall {a}. ActionName a
Types.Stack
| (ResolvedCradle b -> Bool) -> [ResolvedCradle b] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (\ResolvedCradle b
c -> ResolvedCradle b -> Bool
forall {a}. ResolvedCradle a -> Bool
isCabalCradleConfig ResolvedCradle b
c Bool -> Bool -> Bool
|| ResolvedCradle b -> Bool
forall {a}. ResolvedCradle a -> Bool
isNoneCradleConfig ResolvedCradle b
c) [ResolvedCradle b]
cs
= ActionName a
forall {a}. ActionName a
Types.Cabal
| [Bool
True] <- (ResolvedCradle b -> Bool) -> [ResolvedCradle b] -> [Bool]
forall a b. (a -> b) -> [a] -> [b]
map ResolvedCradle b -> Bool
forall {a}. ResolvedCradle a -> Bool
isBiosCradleConfig ([ResolvedCradle b] -> [Bool]) -> [ResolvedCradle b] -> [Bool]
forall a b. (a -> b) -> a -> b
$ (ResolvedCradle b -> Bool)
-> [ResolvedCradle b] -> [ResolvedCradle b]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not (Bool -> Bool)
-> (ResolvedCradle b -> Bool) -> ResolvedCradle b -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ResolvedCradle b -> Bool
forall {a}. ResolvedCradle a -> Bool
isNoneCradleConfig) [ResolvedCradle b]
cs
= ActionName a
forall {a}. ActionName a
Types.Bios
| [Bool
True] <- (ResolvedCradle b -> Bool) -> [ResolvedCradle b] -> [Bool]
forall a b. (a -> b) -> [a] -> [b]
map ResolvedCradle b -> Bool
forall {a}. ResolvedCradle a -> Bool
isDirectCradleConfig ([ResolvedCradle b] -> [Bool]) -> [ResolvedCradle b] -> [Bool]
forall a b. (a -> b) -> a -> b
$ (ResolvedCradle b -> Bool)
-> [ResolvedCradle b] -> [ResolvedCradle b]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not (Bool -> Bool)
-> (ResolvedCradle b -> Bool) -> ResolvedCradle b -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ResolvedCradle b -> Bool
forall {a}. ResolvedCradle a -> Bool
isNoneCradleConfig) [ResolvedCradle b]
cs
= ActionName a
forall {a}. ActionName a
Types.Direct
| Bool
otherwise
= ActionName a
forall {a}. ActionName a
Types.Multi
isStackCradleConfig :: ResolvedCradle a -> Bool
isStackCradleConfig ResolvedCradle a
cfg = case ResolvedCradle a -> ConcreteCradle a
forall a. ResolvedCradle a -> ConcreteCradle a
concreteCradle ResolvedCradle a
cfg of
ConcreteStack{} -> Bool
True
ConcreteCradle a
_ -> Bool
False
isCabalCradleConfig :: ResolvedCradle a -> Bool
isCabalCradleConfig ResolvedCradle a
cfg = case ResolvedCradle a -> ConcreteCradle a
forall a. ResolvedCradle a -> ConcreteCradle a
concreteCradle ResolvedCradle a
cfg of
ConcreteCabal{} -> Bool
True
ConcreteCradle a
_ -> Bool
False
isBiosCradleConfig :: ResolvedCradle a -> Bool
isBiosCradleConfig ResolvedCradle a
cfg = case ResolvedCradle a -> ConcreteCradle a
forall a. ResolvedCradle a -> ConcreteCradle a
concreteCradle ResolvedCradle a
cfg of
ConcreteBios{} -> Bool
True
ConcreteCradle a
_ -> Bool
False
isDirectCradleConfig :: ResolvedCradle a -> Bool
isDirectCradleConfig ResolvedCradle a
cfg = case ResolvedCradle a -> ConcreteCradle a
forall a. ResolvedCradle a -> ConcreteCradle a
concreteCradle ResolvedCradle a
cfg of
ConcreteDirect{} -> Bool
True
ConcreteCradle a
_ -> Bool
False
isNoneCradleConfig :: ResolvedCradle a -> Bool
isNoneCradleConfig ResolvedCradle a
cfg = case ResolvedCradle a -> ConcreteCradle a
forall a. ResolvedCradle a -> ConcreteCradle a
concreteCradle ResolvedCradle a
cfg of
ConcreteNone{} -> Bool
True
ConcreteCradle a
_ -> Bool
False
notNoneType :: ActionName a -> Bool
notNoneType ActionName a
Types.None = Bool
False
notNoneType ActionName a
_ = Bool
True
resolveCradleAction :: LogAction IO (WithSeverity Log) -> (b -> CradleAction a) -> ResolvedCradles b -> FilePath -> ResolvedCradle b -> CradleAction a
resolveCradleAction :: forall b a.
LogAction IO (WithSeverity Log)
-> (b -> CradleAction a)
-> ResolvedCradles b
-> String
-> ResolvedCradle b
-> CradleAction a
resolveCradleAction LogAction IO (WithSeverity Log)
l b -> CradleAction a
buildCustomCradle ResolvedCradles b
cs String
root ResolvedCradle b
cradle =
case ResolvedCradle b -> ConcreteCradle b
forall a. ResolvedCradle a -> ConcreteCradle a
concreteCradle ResolvedCradle b
cradle of
ConcreteCabal CabalType
t -> LogAction IO (WithSeverity Log)
-> ResolvedCradles b
-> String
-> Maybe String
-> CradleProjectConfig
-> CradleAction a
forall b a.
LogAction IO (WithSeverity Log)
-> ResolvedCradles b
-> String
-> Maybe String
-> CradleProjectConfig
-> CradleAction a
cabalCradle LogAction IO (WithSeverity Log)
l ResolvedCradles b
cs String
root (CabalType -> Maybe String
cabalComponent CabalType
t) (String -> Maybe String -> CradleProjectConfig
projectConfigFromMaybe String
root (CabalType -> Maybe String
cabalProjectFile CabalType
t))
ConcreteStack StackType
t -> LogAction IO (WithSeverity Log)
-> String -> Maybe String -> CradleProjectConfig -> CradleAction a
forall a.
LogAction IO (WithSeverity Log)
-> String -> Maybe String -> CradleProjectConfig -> CradleAction a
stackCradle LogAction IO (WithSeverity Log)
l String
root (StackType -> Maybe String
stackComponent StackType
t) (String -> Maybe String -> CradleProjectConfig
projectConfigFromMaybe String
root (StackType -> Maybe String
stackYaml StackType
t))
ConcreteBios Callable
bios Maybe Callable
deps Maybe String
mbGhc -> LogAction IO (WithSeverity Log)
-> String
-> Callable
-> Maybe Callable
-> Maybe String
-> CradleAction a
forall a.
LogAction IO (WithSeverity Log)
-> String
-> Callable
-> Maybe Callable
-> Maybe String
-> CradleAction a
biosCradle LogAction IO (WithSeverity Log)
l String
root Callable
bios Maybe Callable
deps Maybe String
mbGhc
ConcreteDirect [String]
xs -> LogAction IO (WithSeverity Log)
-> String -> [String] -> CradleAction a
forall a.
LogAction IO (WithSeverity Log)
-> String -> [String] -> CradleAction a
directCradle LogAction IO (WithSeverity Log)
l String
root [String]
xs
ConcreteCradle b
ConcreteNone -> CradleAction a
forall a. CradleAction a
noneCradle
ConcreteOther b
a -> b -> CradleAction a
buildCustomCradle b
a
resolveCradleTree :: FilePath -> CradleConfig a -> [ResolvedCradle a]
resolveCradleTree :: forall a. String -> CradleConfig a -> [ResolvedCradle a]
resolveCradleTree String
root (CradleConfig [String]
deps CradleTree a
tree) = String -> [String] -> CradleTree a -> [ResolvedCradle a]
forall {a}.
String -> [String] -> CradleTree a -> [ResolvedCradle a]
go String
root [String]
deps CradleTree a
tree
where
go :: String -> [String] -> CradleTree a -> [ResolvedCradle a]
go String
pfix [String]
deps CradleTree a
tree = case CradleTree a
tree of
Cabal CabalType
t -> [String -> [String] -> ConcreteCradle a -> ResolvedCradle a
forall a.
String -> [String] -> ConcreteCradle a -> ResolvedCradle a
ResolvedCradle String
pfix [String]
deps (CabalType -> ConcreteCradle a
forall a. CabalType -> ConcreteCradle a
ConcreteCabal CabalType
t)]
Stack StackType
t -> [String -> [String] -> ConcreteCradle a -> ResolvedCradle a
forall a.
String -> [String] -> ConcreteCradle a -> ResolvedCradle a
ResolvedCradle String
pfix [String]
deps (StackType -> ConcreteCradle a
forall a. StackType -> ConcreteCradle a
ConcreteStack StackType
t)]
Bios Callable
bios Maybe Callable
dcmd Maybe String
mbGhc -> [String -> [String] -> ConcreteCradle a -> ResolvedCradle a
forall a.
String -> [String] -> ConcreteCradle a -> ResolvedCradle a
ResolvedCradle String
pfix [String]
deps (Callable -> Maybe Callable -> Maybe String -> ConcreteCradle a
forall a.
Callable -> Maybe Callable -> Maybe String -> ConcreteCradle a
ConcreteBios Callable
bios Maybe Callable
dcmd Maybe String
mbGhc)]
Direct [String]
xs -> [String -> [String] -> ConcreteCradle a -> ResolvedCradle a
forall a.
String -> [String] -> ConcreteCradle a -> ResolvedCradle a
ResolvedCradle String
pfix [String]
deps ([String] -> ConcreteCradle a
forall a. [String] -> ConcreteCradle a
ConcreteDirect [String]
xs)]
CradleTree a
None -> [String -> [String] -> ConcreteCradle a -> ResolvedCradle a
forall a.
String -> [String] -> ConcreteCradle a -> ResolvedCradle a
ResolvedCradle String
pfix [String]
deps ConcreteCradle a
forall a. ConcreteCradle a
ConcreteNone]
Other a
a Value
_ -> [String -> [String] -> ConcreteCradle a -> ResolvedCradle a
forall a.
String -> [String] -> ConcreteCradle a -> ResolvedCradle a
ResolvedCradle String
pfix [String]
deps (a -> ConcreteCradle a
forall a. a -> ConcreteCradle a
ConcreteOther a
a)]
CabalMulti CabalType
dc [(String, CabalType)]
xs -> [String -> [String] -> ConcreteCradle a -> ResolvedCradle a
forall a.
String -> [String] -> ConcreteCradle a -> ResolvedCradle a
ResolvedCradle String
p [String]
deps (CabalType -> ConcreteCradle a
forall a. CabalType -> ConcreteCradle a
ConcreteCabal (CabalType
dc CabalType -> CabalType -> CabalType
forall a. Semigroup a => a -> a -> a
<> CabalType
c)) | (String
p, CabalType
c) <- [(String, CabalType)]
xs ]
StackMulti StackType
dc [(String, StackType)]
xs -> [String -> [String] -> ConcreteCradle a -> ResolvedCradle a
forall a.
String -> [String] -> ConcreteCradle a -> ResolvedCradle a
ResolvedCradle String
p [String]
deps (StackType -> ConcreteCradle a
forall a. StackType -> ConcreteCradle a
ConcreteStack (StackType
dc StackType -> StackType -> StackType
forall a. Semigroup a => a -> a -> a
<> StackType
c)) | (String
p, StackType
c) <- [(String, StackType)]
xs ]
Multi [(String, CradleConfig a)]
xs -> [[ResolvedCradle a]] -> [ResolvedCradle a]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [ String -> [String] -> CradleTree a -> [ResolvedCradle a]
go String
pfix' ([String]
deps [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String]
deps') CradleTree a
tree' | (String
pfix', CradleConfig [String]
deps' CradleTree a
tree') <- [(String, CradleConfig a)]
xs]
inferCradleTree :: FilePath -> MaybeT IO (CradleTree a, FilePath)
inferCradleTree :: forall a. String -> MaybeT IO (CradleTree a, String)
inferCradleTree String
fp =
MaybeT IO (CradleTree a, String)
forall {a}. MaybeT IO (CradleTree a, String)
maybeItsBios
MaybeT IO (CradleTree a, String)
-> MaybeT IO (CradleTree a, String)
-> MaybeT IO (CradleTree a, String)
forall a. MaybeT IO a -> MaybeT IO a -> MaybeT IO a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> MaybeT IO (CradleTree a, String)
forall {a}. MaybeT IO (CradleTree a, String)
maybeItsStack
MaybeT IO (CradleTree a, String)
-> MaybeT IO (CradleTree a, String)
-> MaybeT IO (CradleTree a, String)
forall a. MaybeT IO a -> MaybeT IO a -> MaybeT IO a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> MaybeT IO (CradleTree a, String)
forall {a}. MaybeT IO (CradleTree a, String)
maybeItsCabal
where
maybeItsBios :: MaybeT IO (CradleTree a, String)
maybeItsBios = (\String
wdir -> (Callable -> Maybe Callable -> Maybe String -> CradleTree a
forall a.
Callable -> Maybe Callable -> Maybe String -> CradleTree a
Bios (String -> Callable
Program (String -> Callable) -> String -> Callable
forall a b. (a -> b) -> a -> b
$ String
wdir String -> String -> String
</> String
".hie-bios") Maybe Callable
forall a. Maybe a
Nothing Maybe String
forall a. Maybe a
Nothing, String
wdir)) (String -> (CradleTree a, String))
-> MaybeT IO String -> MaybeT IO (CradleTree a, String)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> MaybeT IO String
biosWorkDir String
fp
maybeItsStack :: MaybeT IO (CradleTree a, String)
maybeItsStack = MaybeT IO String
stackExecutable MaybeT IO String
-> MaybeT IO (CradleTree a, String)
-> MaybeT IO (CradleTree a, String)
forall a b. MaybeT IO a -> MaybeT IO b -> MaybeT IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (StackType -> CradleTree a
forall a. StackType -> CradleTree a
Stack (StackType -> CradleTree a) -> StackType -> CradleTree a
forall a b. (a -> b) -> a -> b
$ Maybe String -> Maybe String -> StackType
StackType Maybe String
forall a. Maybe a
Nothing Maybe String
forall a. Maybe a
Nothing,) (String -> (CradleTree a, String))
-> MaybeT IO String -> MaybeT IO (CradleTree a, String)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> MaybeT IO String
stackWorkDir String
fp
maybeItsCabal :: MaybeT IO (CradleTree a, String)
maybeItsCabal = (CabalType -> CradleTree a
forall a. CabalType -> CradleTree a
Cabal (CabalType -> CradleTree a) -> CabalType -> CradleTree a
forall a b. (a -> b) -> a -> b
$ Maybe String -> Maybe String -> CabalType
CabalType Maybe String
forall a. Maybe a
Nothing Maybe String
forall a. Maybe a
Nothing,) (String -> (CradleTree a, String))
-> MaybeT IO String -> MaybeT IO (CradleTree a, String)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> MaybeT IO String
cabalWorkDir String
fp
implicitConfig :: FilePath -> MaybeT IO (CradleConfig a, FilePath)
implicitConfig :: forall a. String -> MaybeT IO (CradleConfig a, String)
implicitConfig = (((CradleTree a, String) -> (CradleConfig a, String))
-> MaybeT IO (CradleTree a, String)
-> MaybeT IO (CradleConfig a, String)
forall a b. (a -> b) -> MaybeT IO a -> MaybeT IO b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (((CradleTree a, String) -> (CradleConfig a, String))
-> MaybeT IO (CradleTree a, String)
-> MaybeT IO (CradleConfig a, String))
-> ((CradleTree a -> CradleConfig a)
-> (CradleTree a, String) -> (CradleConfig a, String))
-> (CradleTree a -> CradleConfig a)
-> MaybeT IO (CradleTree a, String)
-> MaybeT IO (CradleConfig a, String)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (CradleTree a -> CradleConfig a)
-> (CradleTree a, String) -> (CradleConfig a, String)
forall a b c. (a -> b) -> (a, c) -> (b, c)
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first) ([String] -> CradleTree a -> CradleConfig a
forall a. [String] -> CradleTree a -> CradleConfig a
CradleConfig [String]
noDeps) (MaybeT IO (CradleTree a, String)
-> MaybeT IO (CradleConfig a, String))
-> (String -> MaybeT IO (CradleTree a, String))
-> String
-> MaybeT IO (CradleConfig a, String)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> MaybeT IO (CradleTree a, String)
forall a. String -> MaybeT IO (CradleTree a, String)
inferCradleTree
where
noDeps :: [FilePath]
noDeps :: [String]
noDeps = []
yamlConfig :: FilePath -> MaybeT IO FilePath
yamlConfig :: String -> MaybeT IO String
yamlConfig String
fp = do
String
configDir <- String -> MaybeT IO String
yamlConfigDirectory String
fp
String -> MaybeT IO String
forall a. a -> MaybeT IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (String
configDir String -> String -> String
</> String
configFileName)
yamlConfigDirectory :: FilePath -> MaybeT IO FilePath
yamlConfigDirectory :: String -> MaybeT IO String
yamlConfigDirectory = (String -> Bool) -> String -> MaybeT IO String
findFileUpwards (String
configFileName String -> String -> Bool
forall a. Eq a => a -> a -> Bool
==)
readCradleConfig :: Yaml.FromJSON b => FilePath -> IO (CradleConfig b)
readCradleConfig :: forall b. FromJSON b => String -> IO (CradleConfig b)
readCradleConfig String
yamlHie = do
Config b
cfg <- IO (Config b) -> IO (Config b)
forall a. IO a -> IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Config b) -> IO (Config b)) -> IO (Config b) -> IO (Config b)
forall a b. (a -> b) -> a -> b
$ String -> IO (Config b)
forall a. FromJSON a => String -> IO (Config a)
readConfig String
yamlHie
CradleConfig b -> IO (CradleConfig b)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Config b -> CradleConfig b
forall a. Config a -> CradleConfig a
cradle Config b
cfg)
configFileName :: FilePath
configFileName :: String
configFileName = String
"hie.yaml"
argDynamic :: [String]
argDynamic :: [String]
argDynamic = [String
"-dynamic" | Bool
Gap.hostIsDynamic ]
isCabalCradle :: Cradle a -> Bool
isCabalCradle :: forall a. Cradle a -> Bool
isCabalCradle Cradle a
crdl = case CradleAction a -> ActionName a
forall a. CradleAction a -> ActionName a
actionName (Cradle a -> CradleAction a
forall a. Cradle a -> CradleAction a
cradleOptsProg Cradle a
crdl) of
ActionName a
Types.Cabal -> Bool
True
ActionName a
_ -> Bool
False
isStackCradle :: Cradle a -> Bool
isStackCradle :: forall a. Cradle a -> Bool
isStackCradle Cradle a
crdl = case CradleAction a -> ActionName a
forall a. CradleAction a -> ActionName a
actionName (Cradle a -> CradleAction a
forall a. Cradle a -> CradleAction a
cradleOptsProg Cradle a
crdl) of
ActionName a
Types.Stack -> Bool
True
ActionName a
_ -> Bool
False
isDirectCradle :: Cradle a -> Bool
isDirectCradle :: forall a. Cradle a -> Bool
isDirectCradle Cradle a
crdl = case CradleAction a -> ActionName a
forall a. CradleAction a -> ActionName a
actionName (Cradle a -> CradleAction a
forall a. Cradle a -> CradleAction a
cradleOptsProg Cradle a
crdl) of
ActionName a
Types.Direct -> Bool
True
ActionName a
_ -> Bool
False
isBiosCradle :: Cradle a -> Bool
isBiosCradle :: forall a. Cradle a -> Bool
isBiosCradle Cradle a
crdl = case CradleAction a -> ActionName a
forall a. CradleAction a -> ActionName a
actionName (Cradle a -> CradleAction a
forall a. Cradle a -> CradleAction a
cradleOptsProg Cradle a
crdl) of
ActionName a
Types.Bios -> Bool
True
ActionName a
_ -> Bool
False
isMultiCradle :: Cradle a -> Bool
isMultiCradle :: forall a. Cradle a -> Bool
isMultiCradle Cradle a
crdl = case CradleAction a -> ActionName a
forall a. CradleAction a -> ActionName a
actionName (Cradle a -> CradleAction a
forall a. Cradle a -> CradleAction a
cradleOptsProg Cradle a
crdl) of
ActionName a
Types.Multi -> Bool
True
ActionName a
_ -> Bool
False
isNoneCradle :: Cradle a -> Bool
isNoneCradle :: forall a. Cradle a -> Bool
isNoneCradle Cradle a
crdl = case CradleAction a -> ActionName a
forall a. CradleAction a -> ActionName a
actionName (Cradle a -> CradleAction a
forall a. Cradle a -> CradleAction a
cradleOptsProg Cradle a
crdl) of
ActionName a
Types.None -> Bool
True
ActionName a
_ -> Bool
False
isDefaultCradle :: Cradle a -> Bool
isDefaultCradle :: forall a. Cradle a -> Bool
isDefaultCradle Cradle a
crdl = case CradleAction a -> ActionName a
forall a. CradleAction a -> ActionName a
actionName (Cradle a -> CradleAction a
forall a. Cradle a -> CradleAction a
cradleOptsProg Cradle a
crdl) of
ActionName a
Types.Default -> Bool
True
ActionName a
_ -> Bool
False
isOtherCradle :: Cradle a -> Bool
isOtherCradle :: forall a. Cradle a -> Bool
isOtherCradle Cradle a
crdl = case CradleAction a -> ActionName a
forall a. CradleAction a -> ActionName a
actionName (Cradle a -> CradleAction a
forall a. Cradle a -> CradleAction a
cradleOptsProg Cradle a
crdl) of
Types.Other a
_ -> Bool
True
ActionName a
_ -> Bool
False
defaultCradle :: LogAction IO (WithSeverity Log) -> FilePath -> Cradle a
defaultCradle :: forall a. LogAction IO (WithSeverity Log) -> String -> Cradle a
defaultCradle LogAction IO (WithSeverity Log)
l String
cur_dir =
Cradle
{ cradleRootDir :: String
cradleRootDir = String
cur_dir
, cradleLogger :: LogAction IO (WithSeverity Log)
cradleLogger = LogAction IO (WithSeverity Log)
l
, cradleOptsProg :: CradleAction a
cradleOptsProg = CradleAction
{ actionName :: ActionName a
actionName = ActionName a
forall {a}. ActionName a
Types.Default
, runCradle :: String -> [String] -> IO (CradleLoadResult ComponentOptions)
runCradle = \String
_ [String]
_ ->
CradleLoadResult ComponentOptions
-> IO (CradleLoadResult ComponentOptions)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (ComponentOptions -> CradleLoadResult ComponentOptions
forall r. r -> CradleLoadResult r
CradleSuccess ([String] -> String -> [String] -> ComponentOptions
ComponentOptions [String]
argDynamic String
cur_dir []))
, runGhcCmd :: [String] -> IO (CradleLoadResult String)
runGhcCmd = LogAction IO (WithSeverity Log)
-> String -> [String] -> IO (CradleLoadResult String)
runGhcCmdOnPath LogAction IO (WithSeverity Log)
l String
cur_dir
}
}
noneCradle :: CradleAction a
noneCradle :: forall a. CradleAction a
noneCradle =
CradleAction
{ actionName :: ActionName a
actionName = ActionName a
forall {a}. ActionName a
Types.None
, runCradle :: String -> [String] -> IO (CradleLoadResult ComponentOptions)
runCradle = \String
_ [String]
_ -> CradleLoadResult ComponentOptions
-> IO (CradleLoadResult ComponentOptions)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return CradleLoadResult ComponentOptions
forall r. CradleLoadResult r
CradleNone
, runGhcCmd :: [String] -> IO (CradleLoadResult String)
runGhcCmd = \[String]
_ -> CradleLoadResult String -> IO (CradleLoadResult String)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return CradleLoadResult String
forall r. CradleLoadResult r
CradleNone
}
canonicalizeResolvedCradles :: FilePath -> [ResolvedCradle a] -> IO [ResolvedCradle a]
canonicalizeResolvedCradles :: forall a. String -> [ResolvedCradle a] -> IO [ResolvedCradle a]
canonicalizeResolvedCradles String
cur_dir [ResolvedCradle a]
cs =
(ResolvedCradle a -> Down String)
-> [ResolvedCradle a] -> [ResolvedCradle a]
forall b a. Ord b => (a -> b) -> [a] -> [a]
sortOn (String -> Down String
forall a. a -> Down a
Down (String -> Down String)
-> (ResolvedCradle a -> String) -> ResolvedCradle a -> Down String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ResolvedCradle a -> String
forall a. ResolvedCradle a -> String
prefix)
([ResolvedCradle a] -> [ResolvedCradle a])
-> IO [ResolvedCradle a] -> IO [ResolvedCradle a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (ResolvedCradle a -> IO (ResolvedCradle a))
-> [ResolvedCradle a] -> IO [ResolvedCradle a]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM (\ResolvedCradle a
c -> (\String
abs -> ResolvedCradle a
c {prefix :: String
prefix = String
abs}) (String -> ResolvedCradle a) -> IO String -> IO (ResolvedCradle a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> IO String
makeAbsolute (String
cur_dir String -> String -> String
</> ResolvedCradle a -> String
forall a. ResolvedCradle a -> String
prefix ResolvedCradle a
c)) [ResolvedCradle a]
cs
selectCradle :: (a -> FilePath) -> FilePath -> [a] -> Maybe a
selectCradle :: forall a. (a -> String) -> String -> [a] -> Maybe a
selectCradle a -> String
_ String
_ [] = Maybe a
forall a. Maybe a
Nothing
selectCradle a -> String
k String
cur_fp (a
c: [a]
css) =
if a -> String
k a
c String -> String -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isPrefixOf` String
cur_fp
then a -> Maybe a
forall a. a -> Maybe a
Just a
c
else (a -> String) -> String -> [a] -> Maybe a
forall a. (a -> String) -> String -> [a] -> Maybe a
selectCradle a -> String
k String
cur_fp [a]
css
directCradle :: LogAction IO (WithSeverity Log) -> FilePath -> [String] -> CradleAction a
directCradle :: forall a.
LogAction IO (WithSeverity Log)
-> String -> [String] -> CradleAction a
directCradle LogAction IO (WithSeverity Log)
l String
wdir [String]
args
= CradleAction
{ actionName :: ActionName a
actionName = ActionName a
forall {a}. ActionName a
Types.Direct
, runCradle :: String -> [String] -> IO (CradleLoadResult ComponentOptions)
runCradle = \String
_ [String]
_ ->
CradleLoadResult ComponentOptions
-> IO (CradleLoadResult ComponentOptions)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (ComponentOptions -> CradleLoadResult ComponentOptions
forall r. r -> CradleLoadResult r
CradleSuccess ([String] -> String -> [String] -> ComponentOptions
ComponentOptions ([String]
args [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String]
argDynamic) String
wdir []))
, runGhcCmd :: [String] -> IO (CradleLoadResult String)
runGhcCmd = LogAction IO (WithSeverity Log)
-> String -> [String] -> IO (CradleLoadResult String)
runGhcCmdOnPath LogAction IO (WithSeverity Log)
l String
wdir
}
biosCradle :: LogAction IO (WithSeverity Log) -> FilePath -> Callable -> Maybe Callable -> Maybe FilePath -> CradleAction a
biosCradle :: forall a.
LogAction IO (WithSeverity Log)
-> String
-> Callable
-> Maybe Callable
-> Maybe String
-> CradleAction a
biosCradle LogAction IO (WithSeverity Log)
l String
wdir Callable
biosCall Maybe Callable
biosDepsCall Maybe String
mbGhc
= CradleAction
{ actionName :: ActionName a
actionName = ActionName a
forall {a}. ActionName a
Types.Bios
, runCradle :: String -> [String] -> IO (CradleLoadResult ComponentOptions)
runCradle = String
-> Callable
-> Maybe Callable
-> LogAction IO (WithSeverity Log)
-> String
-> [String]
-> IO (CradleLoadResult ComponentOptions)
biosAction String
wdir Callable
biosCall Maybe Callable
biosDepsCall LogAction IO (WithSeverity Log)
l
, runGhcCmd :: [String] -> IO (CradleLoadResult String)
runGhcCmd = \[String]
args -> LogAction IO (WithSeverity Log)
-> String
-> String
-> [String]
-> String
-> IO (CradleLoadResult String)
readProcessWithCwd LogAction IO (WithSeverity Log)
l String
wdir (String -> Maybe String -> String
forall a. a -> Maybe a -> a
fromMaybe String
"ghc" Maybe String
mbGhc) [String]
args String
""
}
biosWorkDir :: FilePath -> MaybeT IO FilePath
biosWorkDir :: String -> MaybeT IO String
biosWorkDir = (String -> Bool) -> String -> MaybeT IO String
findFileUpwards (String
".hie-bios" String -> String -> Bool
forall a. Eq a => a -> a -> Bool
==)
biosDepsAction :: LogAction IO (WithSeverity Log) -> FilePath -> Maybe Callable -> FilePath -> [FilePath] -> IO [FilePath]
biosDepsAction :: LogAction IO (WithSeverity Log)
-> String -> Maybe Callable -> String -> [String] -> IO [String]
biosDepsAction LogAction IO (WithSeverity Log)
l String
wdir (Just Callable
biosDepsCall) String
fp [String]
_prevs = do
CreateProcess
biosDeps' <- Callable -> Maybe String -> IO CreateProcess
callableToProcess Callable
biosDepsCall (String -> Maybe String
forall a. a -> Maybe a
Just String
fp)
(ExitCode
ex, [String]
sout, [String]
serr, [(String
_, Maybe [String]
args)]) <- [String]
-> LogAction IO (WithSeverity Log)
-> String
-> CreateProcess
-> IO (ExitCode, [String], [String], [(String, Maybe [String])])
readProcessWithOutputs [String
hie_bios_output] LogAction IO (WithSeverity Log)
l String
wdir CreateProcess
biosDeps'
case ExitCode
ex of
ExitFailure Int
_ -> String -> IO [String]
forall a. HasCallStack => String -> a
error (String -> IO [String]) -> String -> IO [String]
forall a b. (a -> b) -> a -> b
$ (ExitCode, [String], [String]) -> String
forall a. Show a => a -> String
show (ExitCode
ex, [String]
sout, [String]
serr)
ExitCode
ExitSuccess -> [String] -> IO [String]
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ([String] -> IO [String]) -> [String] -> IO [String]
forall a b. (a -> b) -> a -> b
$ [String] -> Maybe [String] -> [String]
forall a. a -> Maybe a -> a
fromMaybe [] Maybe [String]
args
biosDepsAction LogAction IO (WithSeverity Log)
_ String
_ Maybe Callable
Nothing String
_ [String]
_ = [String] -> IO [String]
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return []
biosAction
:: FilePath
-> Callable
-> Maybe Callable
-> LogAction IO (WithSeverity Log)
-> FilePath
-> [FilePath]
-> IO (CradleLoadResult ComponentOptions)
biosAction :: String
-> Callable
-> Maybe Callable
-> LogAction IO (WithSeverity Log)
-> String
-> [String]
-> IO (CradleLoadResult ComponentOptions)
biosAction String
wdir Callable
bios Maybe Callable
bios_deps LogAction IO (WithSeverity Log)
l String
fp [String]
fps = do
CreateProcess
bios' <- Callable -> Maybe String -> IO CreateProcess
callableToProcess Callable
bios (String -> Maybe String
forall a. a -> Maybe a
Just String
fp)
(ExitCode
ex, [String]
_stdo, [String]
std, [(String
_, Maybe [String]
res),(String
_, Maybe [String]
mb_deps)]) <-
[String]
-> LogAction IO (WithSeverity Log)
-> String
-> CreateProcess
-> IO (ExitCode, [String], [String], [(String, Maybe [String])])
readProcessWithOutputs [String
hie_bios_output, String
hie_bios_deps] LogAction IO (WithSeverity Log)
l String
wdir CreateProcess
bios'
[String]
deps <- case Maybe [String]
mb_deps of
Just [String]
x -> [String] -> IO [String]
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return [String]
x
Maybe [String]
Nothing -> LogAction IO (WithSeverity Log)
-> String -> Maybe Callable -> String -> [String] -> IO [String]
biosDepsAction LogAction IO (WithSeverity Log)
l String
wdir Maybe Callable
bios_deps String
fp [String]
fps
CradleLoadResult ComponentOptions
-> IO (CradleLoadResult ComponentOptions)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (CradleLoadResult ComponentOptions
-> IO (CradleLoadResult ComponentOptions))
-> CradleLoadResult ComponentOptions
-> IO (CradleLoadResult ComponentOptions)
forall a b. (a -> b) -> a -> b
$ (ExitCode, [String], String, [String])
-> [String] -> CradleLoadResult ComponentOptions
makeCradleResult (ExitCode
ex, [String]
std, String
wdir, [String] -> Maybe [String] -> [String]
forall a. a -> Maybe a -> a
fromMaybe [] Maybe [String]
res) [String]
deps
callableToProcess :: Callable -> Maybe String -> IO CreateProcess
callableToProcess :: Callable -> Maybe String -> IO CreateProcess
callableToProcess (Command String
shellCommand) Maybe String
file = do
[(String, String)]
old_env <- IO [(String, String)]
getEnvironment
CreateProcess -> IO CreateProcess
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (CreateProcess -> IO CreateProcess)
-> CreateProcess -> IO CreateProcess
forall a b. (a -> b) -> a -> b
$ (String -> CreateProcess
shell String
shellCommand) { env :: Maybe [(String, String)]
env = ((String, String) -> [(String, String)] -> [(String, String)]
forall a. a -> [a] -> [a]
: [(String, String)]
old_env) ((String, String) -> [(String, String)])
-> (String -> (String, String)) -> String -> [(String, String)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (,) String
hie_bios_arg (String -> [(String, String)])
-> Maybe String -> Maybe [(String, String)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe String
file }
callableToProcess (Program String
path) Maybe String
file = do
String
canon_path <- String -> IO String
canonicalizePath String
path
CreateProcess -> IO CreateProcess
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (CreateProcess -> IO CreateProcess)
-> CreateProcess -> IO CreateProcess
forall a b. (a -> b) -> a -> b
$ String -> [String] -> CreateProcess
proc String
canon_path (Maybe String -> [String]
forall a. Maybe a -> [a]
maybeToList Maybe String
file)
projectFileProcessArgs :: CradleProjectConfig -> [String]
projectFileProcessArgs :: CradleProjectConfig -> [String]
projectFileProcessArgs (ExplicitConfig String
prjFile) = [String
"--project-file", String
prjFile]
projectFileProcessArgs CradleProjectConfig
NoExplicitConfig = []
projectLocationOrDefault :: CradleProjectConfig -> [FilePath]
projectLocationOrDefault :: CradleProjectConfig -> [String]
projectLocationOrDefault = \case
CradleProjectConfig
NoExplicitConfig -> [String
"cabal.project", String
"cabal.project.local"]
(ExplicitConfig String
prjFile) -> [String
prjFile, String
prjFile String -> String -> String
<.> String
"local"]
cabalCradle :: LogAction IO (WithSeverity Log) -> ResolvedCradles b -> FilePath -> Maybe String -> CradleProjectConfig -> CradleAction a
cabalCradle :: forall b a.
LogAction IO (WithSeverity Log)
-> ResolvedCradles b
-> String
-> Maybe String
-> CradleProjectConfig
-> CradleAction a
cabalCradle LogAction IO (WithSeverity Log)
l ResolvedCradles b
cs String
wdir Maybe String
mc CradleProjectConfig
projectFile
= CradleAction
{ actionName :: ActionName a
actionName = ActionName a
forall {a}. ActionName a
Types.Cabal
, runCradle :: String -> [String] -> IO (CradleLoadResult ComponentOptions)
runCradle = \String
fp -> CradleLoadResultT IO ComponentOptions
-> IO (CradleLoadResult ComponentOptions)
forall (m :: * -> *) a.
CradleLoadResultT m a -> m (CradleLoadResult a)
runCradleResultT (CradleLoadResultT IO ComponentOptions
-> IO (CradleLoadResult ComponentOptions))
-> ([String] -> CradleLoadResultT IO ComponentOptions)
-> [String]
-> IO (CradleLoadResult ComponentOptions)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ResolvedCradles b
-> String
-> Maybe String
-> LogAction IO (WithSeverity Log)
-> CradleProjectConfig
-> String
-> [String]
-> CradleLoadResultT IO ComponentOptions
forall a.
ResolvedCradles a
-> String
-> Maybe String
-> LogAction IO (WithSeverity Log)
-> CradleProjectConfig
-> String
-> [String]
-> CradleLoadResultT IO ComponentOptions
cabalAction ResolvedCradles b
cs String
wdir Maybe String
mc LogAction IO (WithSeverity Log)
l CradleProjectConfig
projectFile String
fp
, runGhcCmd :: [String] -> IO (CradleLoadResult String)
runGhcCmd = \[String]
args -> CradleLoadResultT IO String -> IO (CradleLoadResult String)
forall (m :: * -> *) a.
CradleLoadResultT m a -> m (CradleLoadResult a)
runCradleResultT (CradleLoadResultT IO String -> IO (CradleLoadResult String))
-> CradleLoadResultT IO String -> IO (CradleLoadResult String)
forall a b. (a -> b) -> a -> b
$ do
String
buildDir <- IO String -> CradleLoadResultT IO String
forall a. IO a -> CradleLoadResultT IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO String -> CradleLoadResultT IO String)
-> IO String -> CradleLoadResultT IO String
forall a b. (a -> b) -> a -> b
$ String -> IO String
cabalBuildDir String
wdir
IO () -> CradleLoadResultT IO ()
forall a. IO a -> CradleLoadResultT IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> CradleLoadResultT IO ())
-> IO () -> CradleLoadResultT IO ()
forall a b. (a -> b) -> a -> b
$ Bool -> String -> IO ()
createDirectoryIfMissing Bool
True (String
buildDir String -> String -> String
</> String
"tmp")
CreateProcess
cabalProc <- LogAction IO (WithSeverity Log)
-> CradleProjectConfig
-> String
-> String
-> [String]
-> CradleLoadResultT IO CreateProcess
cabalProcess LogAction IO (WithSeverity Log)
l CradleProjectConfig
projectFile String
wdir String
"v2-exec" ([String] -> CradleLoadResultT IO CreateProcess)
-> [String] -> CradleLoadResultT IO CreateProcess
forall a b. (a -> b) -> a -> b
$ [String
"ghc", String
"-v0", String
"--"] [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String]
args
LogAction IO (WithSeverity Log)
-> CreateProcess -> String -> CradleLoadResultT IO String
readProcessWithCwd' LogAction IO (WithSeverity Log)
l CreateProcess
cabalProc String
""
}
cabalProcess :: LogAction IO (WithSeverity Log) -> CradleProjectConfig -> FilePath -> String -> [String] -> CradleLoadResultT IO CreateProcess
cabalProcess :: LogAction IO (WithSeverity Log)
-> CradleProjectConfig
-> String
-> String
-> [String]
-> CradleLoadResultT IO CreateProcess
cabalProcess LogAction IO (WithSeverity Log)
l CradleProjectConfig
cabalProject String
workDir String
command [String]
args = do
(String, String)
ghcDirs <- LogAction IO (WithSeverity Log)
-> CradleProjectConfig
-> String
-> CradleLoadResultT IO (String, String)
cabalGhcDirs LogAction IO (WithSeverity Log)
l CradleProjectConfig
cabalProject String
workDir
[(String, String)]
newEnvironment <- IO [(String, String)] -> CradleLoadResultT IO [(String, String)]
forall a. IO a -> CradleLoadResultT IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO [(String, String)] -> CradleLoadResultT IO [(String, String)])
-> IO [(String, String)] -> CradleLoadResultT IO [(String, String)]
forall a b. (a -> b) -> a -> b
$ (String, String) -> IO [(String, String)]
setupEnvironment (String, String)
ghcDirs
CreateProcess
cabalProc <- IO CreateProcess -> CradleLoadResultT IO CreateProcess
forall a. IO a -> CradleLoadResultT IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO CreateProcess -> CradleLoadResultT IO CreateProcess)
-> IO CreateProcess -> CradleLoadResultT IO CreateProcess
forall a b. (a -> b) -> a -> b
$ (String, String) -> IO CreateProcess
setupCabalCommand (String, String)
ghcDirs
CreateProcess -> CradleLoadResultT IO CreateProcess
forall a. a -> CradleLoadResultT IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (CreateProcess -> CradleLoadResultT IO CreateProcess)
-> CreateProcess -> CradleLoadResultT IO CreateProcess
forall a b. (a -> b) -> a -> b
$ (CreateProcess
cabalProc
{ env :: Maybe [(String, String)]
env = [(String, String)] -> Maybe [(String, String)]
forall a. a -> Maybe a
Just [(String, String)]
newEnvironment
, cwd :: Maybe String
cwd = String -> Maybe String
forall a. a -> Maybe a
Just String
workDir
})
where
processEnvironment :: (FilePath, FilePath) -> [(String, String)]
processEnvironment :: (String, String) -> [(String, String)]
processEnvironment (String
ghcBin, String
libdir) =
[(String
hie_bios_ghc, String
ghcBin), (String
hie_bios_ghc_args, String
"-B" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
libdir)]
setupEnvironment :: (FilePath, FilePath) -> IO [(String, String)]
setupEnvironment :: (String, String) -> IO [(String, String)]
setupEnvironment (String, String)
ghcDirs = do
[(String, String)]
environment <- IO [(String, String)]
getCleanEnvironment
[(String, String)] -> IO [(String, String)]
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([(String, String)] -> IO [(String, String)])
-> [(String, String)] -> IO [(String, String)]
forall a b. (a -> b) -> a -> b
$ (String, String) -> [(String, String)]
processEnvironment (String, String)
ghcDirs [(String, String)] -> [(String, String)] -> [(String, String)]
forall a. [a] -> [a] -> [a]
++ [(String, String)]
environment
setupCabalCommand :: (FilePath, FilePath) -> IO CreateProcess
setupCabalCommand :: (String, String) -> IO CreateProcess
setupCabalCommand (String
ghcBin, String
libdir) = do
String
wrapper_fp <- LogAction IO (WithSeverity Log) -> GhcProc -> String -> IO String
withGhcWrapperTool LogAction IO (WithSeverity Log)
l (String
"ghc", []) String
workDir
String
buildDir <- String -> IO String
cabalBuildDir String
workDir
String
ghcPkgPath <- String -> String -> IO String
withGhcPkgTool String
ghcBin String
libdir
let extraCabalArgs :: [String]
extraCabalArgs =
[ String
"--builddir=" String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
buildDir
, String
command
, String
"--with-compiler", String
wrapper_fp
, String
"--with-hc-pkg", String
ghcPkgPath
] [String] -> [String] -> [String]
forall a. Semigroup a => a -> a -> a
<> CradleProjectConfig -> [String]
projectFileProcessArgs CradleProjectConfig
cabalProject
CreateProcess -> IO CreateProcess
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (CreateProcess -> IO CreateProcess)
-> CreateProcess -> IO CreateProcess
forall a b. (a -> b) -> a -> b
$ String -> [String] -> CreateProcess
proc String
"cabal" ([String]
extraCabalArgs [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String]
args)
withGhcPkgTool :: FilePath -> FilePath -> IO FilePath
withGhcPkgTool :: String -> String -> IO String
withGhcPkgTool String
ghcPathAbs String
libdir = do
let ghcName :: String
ghcName = String -> String
takeFileName String
ghcPathAbs
ghcPkgPath :: String
ghcPkgPath = String -> String
guessGhcPkgFromGhc String
ghcName
if Bool
isWindows
then String -> IO String
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure String
ghcPkgPath
else String -> IO String
withWrapperTool String
ghcPkgPath
where
ghcDir :: String
ghcDir = String -> String
takeDirectory String
ghcPathAbs
guessGhcPkgFromGhc :: String -> String
guessGhcPkgFromGhc String
ghcName =
let ghcPkgName :: Text
ghcPkgName = HasCallStack => Text -> Text -> Text -> Text
Text -> Text -> Text -> Text
T.replace Text
"ghc" Text
"ghc-pkg" (String -> Text
T.pack String
ghcName)
in String
ghcDir String -> String -> String
</> Text -> String
T.unpack Text
ghcPkgName
withWrapperTool :: String -> IO String
withWrapperTool String
ghcPkg = do
let globalPackageDb :: String
globalPackageDb = String
libdir String -> String -> String
</> String
"package.conf.d"
contents :: String
contents = [String] -> String
unlines
[ String
"#!/bin/sh"
, [String] -> String
unwords [String
"exec", String -> String
escapeFilePath String
ghcPkg
, String
"--global-package-db", String -> String
escapeFilePath String
globalPackageDb
, String
"${1+\"$@\"}"
]
]
srcHash :: String
srcHash = Fingerprint -> String
forall a. Show a => a -> String
show (String -> Fingerprint
fingerprintString String
contents)
String -> String -> (String -> IO ()) -> IO String
cacheFile String
"ghc-pkg" String
srcHash ((String -> IO ()) -> IO String) -> (String -> IO ()) -> IO String
forall a b. (a -> b) -> a -> b
$ \String
wrapperFp -> String -> String -> IO ()
writeFile String
wrapperFp String
contents
escapeFilePath :: String -> String
escapeFilePath String
fp = String -> String
trimEnd (String -> String) -> String -> String
forall a b. (a -> b) -> a -> b
$ [String] -> String
escapeArgs [String
fp]
cabalCradleDependencies :: CradleProjectConfig -> FilePath -> FilePath -> IO [FilePath]
cabalCradleDependencies :: CradleProjectConfig -> String -> String -> IO [String]
cabalCradleDependencies CradleProjectConfig
projectFile String
rootDir String
componentDir = do
let relFp :: String
relFp = String -> String -> String
makeRelative String
rootDir String
componentDir
[String]
cabalFiles' <- String -> IO [String]
findCabalFiles String
componentDir
let cabalFiles :: [String]
cabalFiles = (String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (String
relFp String -> String -> String
</>) [String]
cabalFiles'
[String] -> IO [String]
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ([String] -> IO [String]) -> [String] -> IO [String]
forall a b. (a -> b) -> a -> b
$ (String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map String -> String
normalise ([String] -> [String]) -> [String] -> [String]
forall a b. (a -> b) -> a -> b
$ [String]
cabalFiles [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ CradleProjectConfig -> [String]
projectLocationOrDefault CradleProjectConfig
projectFile
findCabalFiles :: FilePath -> IO [FilePath]
findCabalFiles :: String -> IO [String]
findCabalFiles String
wdir = do
[String]
dirContent <- String -> IO [String]
listDirectory String
wdir
[String] -> IO [String]
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ([String] -> IO [String]) -> [String] -> IO [String]
forall a b. (a -> b) -> a -> b
$ (String -> Bool) -> [String] -> [String]
forall a. (a -> Bool) -> [a] -> [a]
filter ((String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
".cabal") (String -> Bool) -> (String -> String) -> String -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String
takeExtension) [String]
dirContent
processCabalWrapperArgs :: [String] -> Maybe (FilePath, [String])
processCabalWrapperArgs :: [String] -> Maybe GhcProc
processCabalWrapperArgs [String]
args =
case [String]
args of
(String
dir: [String]
ghc_args) ->
let final_args :: [String]
final_args =
[String] -> [String]
removeVerbosityOpts
([String] -> [String]) -> [String] -> [String]
forall a b. (a -> b) -> a -> b
$ [String] -> [String]
removeRTS
([String] -> [String]) -> [String] -> [String]
forall a b. (a -> b) -> a -> b
$ [String] -> [String]
removeInteractive [String]
ghc_args
in GhcProc -> Maybe GhcProc
forall a. a -> Maybe a
Just (String
dir, [String]
final_args)
[String]
_ -> Maybe GhcProc
forall a. Maybe a
Nothing
type GhcProc = (FilePath, [String])
withGhcWrapperTool :: LogAction IO (WithSeverity Log) -> GhcProc -> FilePath -> IO FilePath
withGhcWrapperTool :: LogAction IO (WithSeverity Log) -> GhcProc -> String -> IO String
withGhcWrapperTool LogAction IO (WithSeverity Log)
l (String
mbGhc, [String]
ghcArgs) String
wdir = do
let wrapperContents :: String
wrapperContents = if Bool
isWindows then String
cabalWrapperHs else String
cabalWrapper
withExtension :: String -> String
withExtension String
fp = if Bool
isWindows then String
fp String -> String -> String
<.> String
"exe" else String
fp
srcHash :: String
srcHash = Fingerprint -> String
forall a. Show a => a -> String
show (String -> Fingerprint
fingerprintString String
wrapperContents)
String -> String -> (String -> IO ()) -> IO String
cacheFile (String -> String
withExtension String
"wrapper") String
srcHash ((String -> IO ()) -> IO String) -> (String -> IO ()) -> IO String
forall a b. (a -> b) -> a -> b
$ \String
wrapper_fp ->
if Bool
isWindows
then
String -> (String -> IO ()) -> IO ()
forall (m :: * -> *) a.
(MonadIO m, MonadMask m) =>
String -> (String -> m a) -> m a
withSystemTempDirectory String
"hie-bios" ((String -> IO ()) -> IO ()) -> (String -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \ String
tmpDir -> do
let wrapper_hs :: String
wrapper_hs = String
wrapper_fp String -> String -> String
-<.> String
"hs"
String -> String -> IO ()
writeFile String
wrapper_hs String
wrapperContents
let ghcArgsWithExtras :: [String]
ghcArgsWithExtras = [String]
ghcArgs [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String
"-rtsopts=ignore", String
"-outputdir", String
tmpDir, String
"-o", String
wrapper_fp, String
wrapper_hs]
let ghcProc :: CreateProcess
ghcProc = (String -> [String] -> CreateProcess
proc String
mbGhc [String]
ghcArgsWithExtras)
{ cwd :: Maybe String
cwd = String -> Maybe String
forall a. a -> Maybe a
Just String
wdir
}
LogAction IO (WithSeverity Log)
l LogAction IO (WithSeverity Log) -> WithSeverity Log -> IO ()
forall (m :: * -> *) msg. LogAction m msg -> msg -> m ()
<& CreateProcess -> Log
LogCreateProcessRun CreateProcess
ghcProc Log -> Severity -> WithSeverity Log
forall msg. msg -> Severity -> WithSeverity msg
`WithSeverity` Severity
Debug
CreateProcess -> String -> IO String
readCreateProcess CreateProcess
ghcProc String
"" IO String -> (String -> IO ()) -> IO ()
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= String -> IO ()
putStr
else String -> String -> IO ()
writeFile String
wrapper_fp String
wrapperContents
cacheFile :: FilePath -> String -> (FilePath -> IO ()) -> IO FilePath
cacheFile :: String -> String -> (String -> IO ()) -> IO String
cacheFile String
fpName String
srcHash String -> IO ()
populate = do
String
cacheDir <- String -> IO String
getCacheDir String
""
Bool -> String -> IO ()
createDirectoryIfMissing Bool
True String
cacheDir
let newFpName :: String
newFpName = String
cacheDir String -> String -> String
</> (String -> String
dropExtensions String
fpName String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
"-" String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
srcHash) String -> String -> String
<.> String -> String
takeExtensions String
fpName
IO Bool -> IO () -> IO ()
forall (m :: * -> *). Monad m => m Bool -> m () -> m ()
unlessM (String -> IO Bool
doesFileExist String
newFpName) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
String -> IO ()
populate String
newFpName
String -> IO ()
setMode String
newFpName
String -> IO String
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure String
newFpName
where
setMode :: String -> IO ()
setMode String
wrapper_fp = String -> FileMode -> IO ()
setFileMode String
wrapper_fp FileMode
accessModes
cabalBuildDir :: FilePath -> IO FilePath
cabalBuildDir :: String -> IO String
cabalBuildDir String
workDir = do
String
abs_work_dir <- String -> IO String
makeAbsolute String
workDir
let dirHash :: String
dirHash = Fingerprint -> String
forall a. Show a => a -> String
show (String -> Fingerprint
fingerprintString String
abs_work_dir)
String -> IO String
getCacheDir (String
"dist-" String -> String -> String
forall a. Semigroup a => a -> a -> a
<> (Char -> Bool) -> String -> String
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not (Bool -> Bool) -> (Char -> Bool) -> Char -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Bool
isSpace) (String -> String
takeBaseName String
abs_work_dir)String -> String -> String
forall a. Semigroup a => a -> a -> a
<>String
"-"String -> String -> String
forall a. Semigroup a => a -> a -> a
<>String
dirHash)
cabalGhcDirs :: LogAction IO (WithSeverity Log) -> CradleProjectConfig -> FilePath -> CradleLoadResultT IO (FilePath, FilePath)
cabalGhcDirs :: LogAction IO (WithSeverity Log)
-> CradleProjectConfig
-> String
-> CradleLoadResultT IO (String, String)
cabalGhcDirs LogAction IO (WithSeverity Log)
l CradleProjectConfig
cabalProject String
workDir = do
String
libdir <- LogAction IO (WithSeverity Log)
-> String
-> String
-> [String]
-> String
-> CradleLoadResultT IO String
readProcessWithCwd_ LogAction IO (WithSeverity Log)
l String
workDir String
"cabal"
([String
"exec"] [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++
[String]
projectFileArgs [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++
[String
"-v0", String
"--", String
"ghc", String
"--print-libdir"]
)
String
""
String
exe <- LogAction IO (WithSeverity Log)
-> String
-> String
-> [String]
-> String
-> CradleLoadResultT IO String
readProcessWithCwd_ LogAction IO (WithSeverity Log)
l String
workDir String
"cabal"
([ String
"exec"] [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++
[String]
projectFileArgs [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++
[ String
"-v0", String
"--" , String
"ghc", String
"-package-env=-", String
"-ignore-dot-ghci", String
"-e"
, String
"Control.Monad.join (Control.Monad.fmap System.IO.putStr System.Environment.getExecutablePath)"
]
)
String
""
(String, String) -> CradleLoadResultT IO (String, String)
forall a. a -> CradleLoadResultT IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (String -> String
trimEnd String
exe, String -> String
trimEnd String
libdir)
where
projectFileArgs :: [String]
projectFileArgs = CradleProjectConfig -> [String]
projectFileProcessArgs CradleProjectConfig
cabalProject
cabalAction
:: ResolvedCradles a
-> FilePath
-> Maybe String
-> LogAction IO (WithSeverity Log)
-> CradleProjectConfig
-> FilePath
-> [FilePath]
-> CradleLoadResultT IO ComponentOptions
cabalAction :: forall a.
ResolvedCradles a
-> String
-> Maybe String
-> LogAction IO (WithSeverity Log)
-> CradleProjectConfig
-> String
-> [String]
-> CradleLoadResultT IO ComponentOptions
cabalAction (ResolvedCradles String
root [ResolvedCradle a]
cs ProgramVersions
vs) String
workDir Maybe String
mc LogAction IO (WithSeverity Log)
l CradleProjectConfig
projectFile String
fp [String]
fps = do
let
cabalCommand :: String
cabalCommand = String
"v2-repl"
cabal_version :: Maybe Version
cabal_version = ProgramVersions -> Maybe Version
cabalVersion ProgramVersions
vs
ghc_version :: Maybe Version
ghc_version = ProgramVersions -> Maybe Version
ghcVersion ProgramVersions
vs
cabalArgs :: [String]
cabalArgs = case (Maybe Version
cabal_version, Maybe Version
ghc_version) of
(Just Version
cabal, Just Version
ghc)
| Version
ghc Version -> Version -> Bool
forall a. Ord a => a -> a -> Bool
>= [Int] -> Version
makeVersion [Int
9,Int
4]
, Version
cabal Version -> Version -> Bool
forall a. Ord a => a -> a -> Bool
>= [Int] -> Version
makeVersion [Int
3,Int
11]
-> case [String]
fps of
[] -> [String -> Maybe String -> String
forall a. a -> Maybe a -> a
fromMaybe (String -> String
fixTargetPath String
fp) Maybe String
mc]
[String]
_ -> String
"--keep-temp-files"
String -> [String] -> [String]
forall a. a -> [a] -> [a]
: String
"--enable-multi-repl"
String -> [String] -> [String]
forall a. a -> [a] -> [a]
: [String -> Maybe String -> String
forall a. a -> Maybe a -> a
fromMaybe (String -> String
fixTargetPath String
fp) Maybe String
mc]
[String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String -> Maybe String -> String
forall a. a -> Maybe a -> a
fromMaybe (String -> String
fixTargetPath String
old_fp) Maybe String
old_mc
| String
old_fp <- [String]
fps
, Just (ResolvedCradle{concreteCradle :: forall a. ResolvedCradle a -> ConcreteCradle a
concreteCradle = ConcreteCabal CabalType
ct}) <- [(ResolvedCradle a -> String)
-> String -> [ResolvedCradle a] -> Maybe (ResolvedCradle a)
forall a. (a -> String) -> String -> [a] -> Maybe a
selectCradle ResolvedCradle a -> String
forall a. ResolvedCradle a -> String
prefix String
old_fp [ResolvedCradle a]
cs]
, (String -> Maybe String -> CradleProjectConfig
projectConfigFromMaybe String
root (CabalType -> Maybe String
cabalProjectFile CabalType
ct)) CradleProjectConfig -> CradleProjectConfig -> Bool
forall a. Eq a => a -> a -> Bool
== CradleProjectConfig
projectFile
, let old_mc :: Maybe String
old_mc = CabalType -> Maybe String
cabalComponent CabalType
ct
]
(Maybe Version, Maybe Version)
_ -> [String -> Maybe String -> String
forall a. a -> Maybe a -> a
fromMaybe (String -> String
fixTargetPath String
fp) Maybe String
mc]
CreateProcess
cabalProc <- LogAction IO (WithSeverity Log)
-> CradleProjectConfig
-> String
-> String
-> [String]
-> CradleLoadResultT IO CreateProcess
cabalProcess LogAction IO (WithSeverity Log)
l CradleProjectConfig
projectFile String
workDir String
cabalCommand [String]
cabalArgs CradleLoadResultT IO CreateProcess
-> (CradleError -> IO CradleError)
-> CradleLoadResultT IO CreateProcess
forall (m :: * -> *) a.
Monad m =>
CradleLoadResultT m a
-> (CradleError -> m CradleError) -> CradleLoadResultT m a
`modCradleError` \CradleError
err -> do
[String]
deps <- CradleProjectConfig -> String -> String -> IO [String]
cabalCradleDependencies CradleProjectConfig
projectFile String
workDir String
workDir
CradleError -> IO CradleError
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (CradleError -> IO CradleError) -> CradleError -> IO CradleError
forall a b. (a -> b) -> a -> b
$ CradleError
err { cradleErrorDependencies :: [String]
cradleErrorDependencies = CradleError -> [String]
cradleErrorDependencies CradleError
err [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String]
deps }
(ExitCode
ex, [String]
output, [String]
stde, [(String
_, Maybe [String]
maybeArgs)]) <- IO (ExitCode, [String], [String], [(String, Maybe [String])])
-> CradleLoadResultT
IO (ExitCode, [String], [String], [(String, Maybe [String])])
forall a. IO a -> CradleLoadResultT IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (ExitCode, [String], [String], [(String, Maybe [String])])
-> CradleLoadResultT
IO (ExitCode, [String], [String], [(String, Maybe [String])]))
-> IO (ExitCode, [String], [String], [(String, Maybe [String])])
-> CradleLoadResultT
IO (ExitCode, [String], [String], [(String, Maybe [String])])
forall a b. (a -> b) -> a -> b
$ [String]
-> LogAction IO (WithSeverity Log)
-> String
-> CreateProcess
-> IO (ExitCode, [String], [String], [(String, Maybe [String])])
readProcessWithOutputs [String
hie_bios_output] LogAction IO (WithSeverity Log)
l String
workDir CreateProcess
cabalProc
let args :: [String]
args = [String] -> Maybe [String] -> [String]
forall a. a -> Maybe a -> a
fromMaybe [] Maybe [String]
maybeArgs
let errorDetails :: [String]
errorDetails =
[String
"Failed command: " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> CmdSpec -> String
prettyCmdSpec (CreateProcess -> CmdSpec
cmdspec CreateProcess
cabalProc)
, [String] -> String
unlines [String]
output
, [String] -> String
unlines [String]
stde
, [String] -> String
unlines ([String] -> String) -> [String] -> String
forall a b. (a -> b) -> a -> b
$ [String]
args
, String
"Process Environment:"]
[String] -> [String] -> [String]
forall a. Semigroup a => a -> a -> a
<> CreateProcess -> [String]
prettyProcessEnv CreateProcess
cabalProc
Bool -> CradleLoadResultT IO () -> CradleLoadResultT IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (ExitCode
ex ExitCode -> ExitCode -> Bool
forall a. Eq a => a -> a -> Bool
/= ExitCode
ExitSuccess) (CradleLoadResultT IO () -> CradleLoadResultT IO ())
-> CradleLoadResultT IO () -> CradleLoadResultT IO ()
forall a b. (a -> b) -> a -> b
$ do
[String]
deps <- IO [String] -> CradleLoadResultT IO [String]
forall a. IO a -> CradleLoadResultT IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO [String] -> CradleLoadResultT IO [String])
-> IO [String] -> CradleLoadResultT IO [String]
forall a b. (a -> b) -> a -> b
$ CradleProjectConfig -> String -> String -> IO [String]
cabalCradleDependencies CradleProjectConfig
projectFile String
workDir String
workDir
let cmd :: String
cmd = [String] -> String
forall a. Show a => a -> String
show ([String
"cabal", String
cabalCommand] [String] -> [String] -> [String]
forall a. Semigroup a => a -> a -> a
<> [String]
cabalArgs)
let errorMsg :: String
errorMsg = String
"Failed to run " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
cmd String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
" in directory \"" String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
workDir String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
"\". Consult the logs for full command and error."
CradleError -> CradleLoadResultT IO ()
forall (m :: * -> *) a.
Monad m =>
CradleError -> CradleLoadResultT m a
throwCE ([String] -> ExitCode -> [String] -> CradleError
CradleError [String]
deps ExitCode
ex ([String
errorMsg] [String] -> [String] -> [String]
forall a. Semigroup a => a -> a -> a
<> [String]
errorDetails))
case [String] -> Maybe GhcProc
processCabalWrapperArgs [String]
args of
Maybe GhcProc
Nothing -> do
[String]
deps <- IO [String] -> CradleLoadResultT IO [String]
forall a. IO a -> CradleLoadResultT IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO [String] -> CradleLoadResultT IO [String])
-> IO [String] -> CradleLoadResultT IO [String]
forall a b. (a -> b) -> a -> b
$ CradleProjectConfig -> String -> String -> IO [String]
cabalCradleDependencies CradleProjectConfig
projectFile String
workDir String
workDir
CradleError -> CradleLoadResultT IO ComponentOptions
forall (m :: * -> *) a.
Monad m =>
CradleError -> CradleLoadResultT m a
throwCE ([String] -> ExitCode -> [String] -> CradleError
CradleError [String]
deps ExitCode
ex ([String] -> CradleError) -> [String] -> CradleError
forall a b. (a -> b) -> a -> b
$
([String
"Failed to parse result of calling cabal" ] [String] -> [String] -> [String]
forall a. Semigroup a => a -> a -> a
<> [String]
errorDetails))
Just (String
componentDir, [String]
final_args) -> do
[String]
deps <- IO [String] -> CradleLoadResultT IO [String]
forall a. IO a -> CradleLoadResultT IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO [String] -> CradleLoadResultT IO [String])
-> IO [String] -> CradleLoadResultT IO [String]
forall a b. (a -> b) -> a -> b
$ CradleProjectConfig -> String -> String -> IO [String]
cabalCradleDependencies CradleProjectConfig
projectFile String
workDir String
componentDir
IO (CradleLoadResult ComponentOptions)
-> CradleLoadResultT IO ComponentOptions
forall (m :: * -> *) a.
m (CradleLoadResult a) -> CradleLoadResultT m a
CradleLoadResultT (IO (CradleLoadResult ComponentOptions)
-> CradleLoadResultT IO ComponentOptions)
-> IO (CradleLoadResult ComponentOptions)
-> CradleLoadResultT IO ComponentOptions
forall a b. (a -> b) -> a -> b
$ CradleLoadResult ComponentOptions
-> IO (CradleLoadResult ComponentOptions)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (CradleLoadResult ComponentOptions
-> IO (CradleLoadResult ComponentOptions))
-> CradleLoadResult ComponentOptions
-> IO (CradleLoadResult ComponentOptions)
forall a b. (a -> b) -> a -> b
$ (ExitCode, [String], String, [String])
-> [String] -> CradleLoadResult ComponentOptions
makeCradleResult (ExitCode
ex, [String]
stde, String
componentDir, [String]
final_args) [String]
deps
where
fixTargetPath :: String -> String
fixTargetPath String
x
| Bool
isWindows Bool -> Bool -> Bool
&& String -> Bool
hasDrive String
x = String -> String -> String
makeRelative String
workDir String
x
| Bool
otherwise = String
x
removeInteractive :: [String] -> [String]
removeInteractive :: [String] -> [String]
removeInteractive = (String -> Bool) -> [String] -> [String]
forall a. (a -> Bool) -> [a] -> [a]
filter (String -> String -> Bool
forall a. Eq a => a -> a -> Bool
/= String
"--interactive")
data InRTS = OutsideRTS | InsideRTS
removeRTS :: [String] -> [String]
removeRTS :: [String] -> [String]
removeRTS = InRTS -> [String] -> [String]
go InRTS
OutsideRTS
where
go :: InRTS -> [String] -> [String]
go :: InRTS -> [String] -> [String]
go InRTS
_ [] = []
go InRTS
OutsideRTS (String
y:[String]
ys)
| String
"+RTS" String -> String -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isPrefixOf` String
y = InRTS -> [String] -> [String]
go (if String
"-RTS" String -> String -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isSuffixOf` String
y then InRTS
OutsideRTS else InRTS
InsideRTS) [String]
ys
| Bool
otherwise = String
y String -> [String] -> [String]
forall a. a -> [a] -> [a]
: InRTS -> [String] -> [String]
go InRTS
OutsideRTS [String]
ys
go InRTS
InsideRTS (String
y:[String]
ys) = InRTS -> [String] -> [String]
go (if String
"-RTS" String -> String -> Bool
forall a. Eq a => [a] -> [a] -> Bool
`isSuffixOf` String
y then InRTS
OutsideRTS else InRTS
InsideRTS) [String]
ys
removeVerbosityOpts :: [String] -> [String]
removeVerbosityOpts :: [String] -> [String]
removeVerbosityOpts = (String -> Bool) -> [String] -> [String]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool -> Bool
(&&) (Bool -> Bool -> Bool)
-> (String -> Bool) -> String -> Bool -> Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (String -> String -> Bool
forall a. Eq a => a -> a -> Bool
/= String
"-v0") (String -> Bool -> Bool) -> (String -> Bool) -> String -> Bool
forall a b. (String -> a -> b) -> (String -> a) -> String -> b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> (String -> String -> Bool
forall a. Eq a => a -> a -> Bool
/= String
"-w"))
cabalWorkDir :: FilePath -> MaybeT IO FilePath
cabalWorkDir :: String -> MaybeT IO String
cabalWorkDir String
wdir =
(String -> Bool) -> String -> MaybeT IO String
findFileUpwards (String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
"cabal.project") String
wdir
MaybeT IO String -> MaybeT IO String -> MaybeT IO String
forall a. MaybeT IO a -> MaybeT IO a -> MaybeT IO a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (String -> Bool) -> String -> MaybeT IO String
findFileUpwards (\String
fp -> String -> String
takeExtension String
fp String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
".cabal") String
wdir
data CradleProjectConfig
= NoExplicitConfig
| ExplicitConfig FilePath
deriving CradleProjectConfig -> CradleProjectConfig -> Bool
(CradleProjectConfig -> CradleProjectConfig -> Bool)
-> (CradleProjectConfig -> CradleProjectConfig -> Bool)
-> Eq CradleProjectConfig
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: CradleProjectConfig -> CradleProjectConfig -> Bool
== :: CradleProjectConfig -> CradleProjectConfig -> Bool
$c/= :: CradleProjectConfig -> CradleProjectConfig -> Bool
/= :: CradleProjectConfig -> CradleProjectConfig -> Bool
Eq
projectConfigFromMaybe :: FilePath -> Maybe FilePath -> CradleProjectConfig
projectConfigFromMaybe :: String -> Maybe String -> CradleProjectConfig
projectConfigFromMaybe String
_wdir Maybe String
Nothing = CradleProjectConfig
NoExplicitConfig
projectConfigFromMaybe String
wdir (Just String
fp) = String -> CradleProjectConfig
ExplicitConfig (String
wdir String -> String -> String
</> String
fp)
stackYamlProcessArgs :: CradleProjectConfig -> [String]
stackYamlProcessArgs :: CradleProjectConfig -> [String]
stackYamlProcessArgs (ExplicitConfig String
yaml) = [String
"--stack-yaml", String
yaml]
stackYamlProcessArgs CradleProjectConfig
NoExplicitConfig = []
stackYamlLocationOrDefault :: CradleProjectConfig -> FilePath
stackYamlLocationOrDefault :: CradleProjectConfig -> String
stackYamlLocationOrDefault CradleProjectConfig
NoExplicitConfig = String
"stack.yaml"
stackYamlLocationOrDefault (ExplicitConfig String
yaml) = String
yaml
stackCradle :: LogAction IO (WithSeverity Log) -> FilePath -> Maybe String -> CradleProjectConfig -> CradleAction a
stackCradle :: forall a.
LogAction IO (WithSeverity Log)
-> String -> Maybe String -> CradleProjectConfig -> CradleAction a
stackCradle LogAction IO (WithSeverity Log)
l String
wdir Maybe String
mc CradleProjectConfig
syaml =
CradleAction
{ actionName :: ActionName a
actionName = ActionName a
forall {a}. ActionName a
Types.Stack
, runCradle :: String -> [String] -> IO (CradleLoadResult ComponentOptions)
runCradle = String
-> Maybe String
-> CradleProjectConfig
-> LogAction IO (WithSeverity Log)
-> String
-> [String]
-> IO (CradleLoadResult ComponentOptions)
stackAction String
wdir Maybe String
mc CradleProjectConfig
syaml LogAction IO (WithSeverity Log)
l
, runGhcCmd :: [String] -> IO (CradleLoadResult String)
runGhcCmd = \[String]
args -> CradleLoadResultT IO String -> IO (CradleLoadResult String)
forall (m :: * -> *) a.
CradleLoadResultT m a -> m (CradleLoadResult a)
runCradleResultT (CradleLoadResultT IO String -> IO (CradleLoadResult String))
-> CradleLoadResultT IO String -> IO (CradleLoadResult String)
forall a b. (a -> b) -> a -> b
$ do
String
_ <- LogAction IO (WithSeverity Log)
-> String
-> String
-> [String]
-> String
-> CradleLoadResultT IO String
readProcessWithCwd_ LogAction IO (WithSeverity Log)
l String
wdir String
"stack" (CradleProjectConfig -> [String]
stackYamlProcessArgs CradleProjectConfig
syaml [String] -> [String] -> [String]
forall a. Semigroup a => a -> a -> a
<> [String
"setup", String
"--silent"]) String
""
LogAction IO (WithSeverity Log)
-> String
-> String
-> [String]
-> String
-> CradleLoadResultT IO String
readProcessWithCwd_ LogAction IO (WithSeverity Log)
l String
wdir String
"stack"
(CradleProjectConfig -> [String]
stackYamlProcessArgs CradleProjectConfig
syaml [String] -> [String] -> [String]
forall a. Semigroup a => a -> a -> a
<> [String
"exec", String
"ghc", String
"--"] [String] -> [String] -> [String]
forall a. Semigroup a => a -> a -> a
<> [String]
args)
String
""
}
stackCradleDependencies :: FilePath -> FilePath -> CradleProjectConfig -> IO [FilePath]
stackCradleDependencies :: String -> String -> CradleProjectConfig -> IO [String]
stackCradleDependencies String
wdir String
componentDir CradleProjectConfig
syaml = do
let relFp :: String
relFp = String -> String -> String
makeRelative String
wdir String
componentDir
[String]
cabalFiles' <- String -> IO [String]
findCabalFiles String
componentDir
let cabalFiles :: [String]
cabalFiles = (String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (String
relFp String -> String -> String
</>) [String]
cabalFiles'
[String] -> IO [String]
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ([String] -> IO [String]) -> [String] -> IO [String]
forall a b. (a -> b) -> a -> b
$ (String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map String -> String
normalise ([String] -> [String]) -> [String] -> [String]
forall a b. (a -> b) -> a -> b
$
[String]
cabalFiles [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String
relFp String -> String -> String
</> String
"package.yaml", CradleProjectConfig -> String
stackYamlLocationOrDefault CradleProjectConfig
syaml]
stackAction
:: FilePath
-> Maybe String
-> CradleProjectConfig
-> LogAction IO (WithSeverity Log)
-> FilePath
-> [FilePath]
-> IO (CradleLoadResult ComponentOptions)
stackAction :: String
-> Maybe String
-> CradleProjectConfig
-> LogAction IO (WithSeverity Log)
-> String
-> [String]
-> IO (CradleLoadResult ComponentOptions)
stackAction String
workDir Maybe String
mc CradleProjectConfig
syaml LogAction IO (WithSeverity Log)
l String
_fp [String]
_fps = do
let ghcProcArgs :: GhcProc
ghcProcArgs = (String
"stack", CradleProjectConfig -> [String]
stackYamlProcessArgs CradleProjectConfig
syaml [String] -> [String] -> [String]
forall a. Semigroup a => a -> a -> a
<> [String
"exec", String
"ghc", String
"--"])
String
wrapper_fp <- LogAction IO (WithSeverity Log) -> GhcProc -> String -> IO String
withGhcWrapperTool LogAction IO (WithSeverity Log)
l GhcProc
ghcProcArgs String
workDir
(ExitCode
ex1, [String]
_stdo, [String]
stde, [(String
_, Maybe [String]
maybeArgs)]) <-
[String]
-> LogAction IO (WithSeverity Log)
-> String
-> CreateProcess
-> IO (ExitCode, [String], [String], [(String, Maybe [String])])
readProcessWithOutputs [String
hie_bios_output] LogAction IO (WithSeverity Log)
l String
workDir
(CreateProcess
-> IO (ExitCode, [String], [String], [(String, Maybe [String])]))
-> CreateProcess
-> IO (ExitCode, [String], [String], [(String, Maybe [String])])
forall a b. (a -> b) -> a -> b
$ CradleProjectConfig -> [String] -> CreateProcess
stackProcess CradleProjectConfig
syaml
([String] -> CreateProcess) -> [String] -> CreateProcess
forall a b. (a -> b) -> a -> b
$ [String
"repl", String
"--no-nix-pure", String
"--with-ghc", String
wrapper_fp]
[String] -> [String] -> [String]
forall a. Semigroup a => a -> a -> a
<> [ String
comp | Just String
comp <- [Maybe String
mc] ]
(ExitCode
ex2, [String]
pkg_args, [String]
stdr, [(String, Maybe [String])]
_) <-
[String]
-> LogAction IO (WithSeverity Log)
-> String
-> CreateProcess
-> IO (ExitCode, [String], [String], [(String, Maybe [String])])
readProcessWithOutputs [String
hie_bios_output] LogAction IO (WithSeverity Log)
l String
workDir
(CreateProcess
-> IO (ExitCode, [String], [String], [(String, Maybe [String])]))
-> CreateProcess
-> IO (ExitCode, [String], [String], [(String, Maybe [String])])
forall a b. (a -> b) -> a -> b
$ CradleProjectConfig -> [String] -> CreateProcess
stackProcess CradleProjectConfig
syaml [String
"path", String
"--ghc-package-path"]
let split_pkgs :: [String]
split_pkgs = (String -> [String]) -> [String] -> [String]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap String -> [String]
splitSearchPath [String]
pkg_args
pkg_ghc_args :: [String]
pkg_ghc_args = (String -> [String]) -> [String] -> [String]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (\String
p -> [String
"-package-db", String
p] ) [String]
split_pkgs
args :: [String]
args = [String] -> Maybe [String] -> [String]
forall a. a -> Maybe a -> a
fromMaybe [] Maybe [String]
maybeArgs
case [String] -> Maybe GhcProc
processCabalWrapperArgs [String]
args of
Maybe GhcProc
Nothing -> do
[String]
deps <- String -> String -> CradleProjectConfig -> IO [String]
stackCradleDependencies String
workDir String
workDir CradleProjectConfig
syaml
CradleLoadResult ComponentOptions
-> IO (CradleLoadResult ComponentOptions)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (CradleLoadResult ComponentOptions
-> IO (CradleLoadResult ComponentOptions))
-> CradleLoadResult ComponentOptions
-> IO (CradleLoadResult ComponentOptions)
forall a b. (a -> b) -> a -> b
$ CradleError -> CradleLoadResult ComponentOptions
forall r. CradleError -> CradleLoadResult r
CradleFail
([String] -> ExitCode -> [String] -> CradleError
CradleError [String]
deps ExitCode
ex1 ([String] -> CradleError) -> [String] -> CradleError
forall a b. (a -> b) -> a -> b
$
[ String
"Failed to parse result of calling stack" ]
[String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String]
stde
[String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String]
args
)
Just (String
componentDir, [String]
ghc_args) -> do
[String]
deps <- String -> String -> CradleProjectConfig -> IO [String]
stackCradleDependencies String
workDir String
componentDir CradleProjectConfig
syaml
CradleLoadResult ComponentOptions
-> IO (CradleLoadResult ComponentOptions)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (CradleLoadResult ComponentOptions
-> IO (CradleLoadResult ComponentOptions))
-> CradleLoadResult ComponentOptions
-> IO (CradleLoadResult ComponentOptions)
forall a b. (a -> b) -> a -> b
$ (ExitCode, [String], String, [String])
-> [String] -> CradleLoadResult ComponentOptions
makeCradleResult
( [ExitCode] -> ExitCode
combineExitCodes [ExitCode
ex1, ExitCode
ex2]
, [String]
stde [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String]
stdr, String
componentDir
, [String]
ghc_args [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ [String]
pkg_ghc_args
)
[String]
deps
stackProcess :: CradleProjectConfig -> [String] -> CreateProcess
stackProcess :: CradleProjectConfig -> [String] -> CreateProcess
stackProcess CradleProjectConfig
syaml [String]
args = String -> [String] -> CreateProcess
proc String
"stack" ([String] -> CreateProcess) -> [String] -> CreateProcess
forall a b. (a -> b) -> a -> b
$ CradleProjectConfig -> [String]
stackYamlProcessArgs CradleProjectConfig
syaml [String] -> [String] -> [String]
forall a. Semigroup a => a -> a -> a
<> [String]
args
combineExitCodes :: [ExitCode] -> ExitCode
combineExitCodes :: [ExitCode] -> ExitCode
combineExitCodes = (ExitCode -> ExitCode -> ExitCode)
-> ExitCode -> [ExitCode] -> ExitCode
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr ExitCode -> ExitCode -> ExitCode
go ExitCode
ExitSuccess
where
go :: ExitCode -> ExitCode -> ExitCode
go ExitCode
ExitSuccess ExitCode
b = ExitCode
b
go ExitCode
a ExitCode
_ = ExitCode
a
stackExecutable :: MaybeT IO FilePath
stackExecutable :: MaybeT IO String
stackExecutable = IO (Maybe String) -> MaybeT IO String
forall (m :: * -> *) a. m (Maybe a) -> MaybeT m a
MaybeT (IO (Maybe String) -> MaybeT IO String)
-> IO (Maybe String) -> MaybeT IO String
forall a b. (a -> b) -> a -> b
$ String -> IO (Maybe String)
findExecutable String
"stack"
stackWorkDir :: FilePath -> MaybeT IO FilePath
stackWorkDir :: String -> MaybeT IO String
stackWorkDir = (String -> Bool) -> String -> MaybeT IO String
findFileUpwards String -> Bool
forall {a}. (Eq a, IsString a) => a -> Bool
isStack
where
isStack :: a -> Bool
isStack a
name = a
name a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
"stack.yaml"
findFileUpwards :: (FilePath -> Bool) -> FilePath -> MaybeT IO FilePath
findFileUpwards :: (String -> Bool) -> String -> MaybeT IO String
findFileUpwards String -> Bool
p String
dir = do
[String]
cnts <-
IO [String] -> MaybeT IO [String]
forall a. IO a -> MaybeT IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO
(IO [String] -> MaybeT IO [String])
-> IO [String] -> MaybeT IO [String]
forall a b. (a -> b) -> a -> b
$ (IOError -> Maybe [String])
-> ([String] -> IO [String]) -> IO [String] -> IO [String]
forall e b a.
Exception e =>
(e -> Maybe b) -> (b -> IO a) -> IO a -> IO a
handleJust
(\(IOError
e :: IOError) -> if IOError -> Bool
isPermissionError IOError
e then [String] -> Maybe [String]
forall a. a -> Maybe a
Just [] else Maybe [String]
forall a. Maybe a
Nothing)
[String] -> IO [String]
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
((String -> Bool) -> String -> IO [String]
findFile String -> Bool
p String
dir)
case [String]
cnts of
[] | String
dir' String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
dir -> String -> MaybeT IO String
forall a. String -> MaybeT IO a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"No cabal files"
| Bool
otherwise -> (String -> Bool) -> String -> MaybeT IO String
findFileUpwards String -> Bool
p String
dir'
String
_ : [String]
_ -> String -> MaybeT IO String
forall a. a -> MaybeT IO a
forall (m :: * -> *) a. Monad m => a -> m a
return String
dir
where dir' :: String
dir' = String -> String
takeDirectory String
dir
findFile :: (FilePath -> Bool) -> FilePath -> IO [FilePath]
findFile :: (String -> Bool) -> String -> IO [String]
findFile String -> Bool
p String
dir = do
Bool
b <- String -> IO Bool
doesDirectoryExist String
dir
if Bool
b then IO [String]
getFiles IO [String] -> ([String] -> IO [String]) -> IO [String]
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (String -> IO Bool) -> [String] -> IO [String]
forall (m :: * -> *) a.
Applicative m =>
(a -> m Bool) -> [a] -> m [a]
filterM String -> IO Bool
doesPredFileExist else [String] -> IO [String]
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return []
where
getFiles :: IO [String]
getFiles = (String -> Bool) -> [String] -> [String]
forall a. (a -> Bool) -> [a] -> [a]
filter String -> Bool
p ([String] -> [String]) -> IO [String] -> IO [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> IO [String]
getDirectoryContents String
dir
doesPredFileExist :: String -> IO Bool
doesPredFileExist String
file = String -> IO Bool
doesFileExist (String -> IO Bool) -> String -> IO Bool
forall a b. (a -> b) -> a -> b
$ String
dir String -> String -> String
</> String
file
getCleanEnvironment :: IO [(String, String)]
getCleanEnvironment :: IO [(String, String)]
getCleanEnvironment = do
HashMap String String -> [(String, String)]
forall k v. HashMap k v -> [(k, v)]
Map.toList (HashMap String String -> [(String, String)])
-> ([(String, String)] -> HashMap String String)
-> [(String, String)]
-> [(String, String)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> HashMap String String -> HashMap String String
forall k v. (Eq k, Hashable k) => k -> HashMap k v -> HashMap k v
Map.delete String
"GHC_PACKAGE_PATH" (HashMap String String -> HashMap String String)
-> ([(String, String)] -> HashMap String String)
-> [(String, String)]
-> HashMap String String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [(String, String)] -> HashMap String String
forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
Map.fromList ([(String, String)] -> [(String, String)])
-> IO [(String, String)] -> IO [(String, String)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IO [(String, String)]
getEnvironment
type Outputs = [OutputName]
type OutputName = String
readProcessWithOutputs
:: Outputs
-> LogAction IO (WithSeverity Log)
-> FilePath
-> CreateProcess
-> IO (ExitCode, [String], [String], [(OutputName, Maybe [String])])
readProcessWithOutputs :: [String]
-> LogAction IO (WithSeverity Log)
-> String
-> CreateProcess
-> IO (ExitCode, [String], [String], [(String, Maybe [String])])
readProcessWithOutputs [String]
outputNames LogAction IO (WithSeverity Log)
l String
workDir CreateProcess
cp = (ContT
(ExitCode, [String], [String], [(String, Maybe [String])])
IO
(ExitCode, [String], [String], [(String, Maybe [String])])
-> ((ExitCode, [String], [String], [(String, Maybe [String])])
-> IO (ExitCode, [String], [String], [(String, Maybe [String])]))
-> IO (ExitCode, [String], [String], [(String, Maybe [String])]))
-> ((ExitCode, [String], [String], [(String, Maybe [String])])
-> IO (ExitCode, [String], [String], [(String, Maybe [String])]))
-> ContT
(ExitCode, [String], [String], [(String, Maybe [String])])
IO
(ExitCode, [String], [String], [(String, Maybe [String])])
-> IO (ExitCode, [String], [String], [(String, Maybe [String])])
forall a b c. (a -> b -> c) -> b -> a -> c
flip ContT
(ExitCode, [String], [String], [(String, Maybe [String])])
IO
(ExitCode, [String], [String], [(String, Maybe [String])])
-> ((ExitCode, [String], [String], [(String, Maybe [String])])
-> IO (ExitCode, [String], [String], [(String, Maybe [String])]))
-> IO (ExitCode, [String], [String], [(String, Maybe [String])])
forall {k} (r :: k) (m :: k -> *) a.
ContT r m a -> (a -> m r) -> m r
runContT (ExitCode, [String], [String], [(String, Maybe [String])])
-> IO (ExitCode, [String], [String], [(String, Maybe [String])])
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (ContT
(ExitCode, [String], [String], [(String, Maybe [String])])
IO
(ExitCode, [String], [String], [(String, Maybe [String])])
-> IO (ExitCode, [String], [String], [(String, Maybe [String])]))
-> ContT
(ExitCode, [String], [String], [(String, Maybe [String])])
IO
(ExitCode, [String], [String], [(String, Maybe [String])])
-> IO (ExitCode, [String], [String], [(String, Maybe [String])])
forall a b. (a -> b) -> a -> b
$ do
[(String, String)]
old_env <- IO [(String, String)]
-> ContT
(ExitCode, [String], [String], [(String, Maybe [String])])
IO
[(String, String)]
forall a.
IO a
-> ContT
(ExitCode, [String], [String], [(String, Maybe [String])]) IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO IO [(String, String)]
getCleanEnvironment
[(String, String)]
output_files <- (String
-> ContT
(ExitCode, [String], [String], [(String, Maybe [String])])
IO
(String, String))
-> [String]
-> ContT
(ExitCode, [String], [String], [(String, Maybe [String])])
IO
[(String, String)]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse ([(String, String)]
-> String
-> ContT
(ExitCode, [String], [String], [(String, Maybe [String])])
IO
(String, String)
forall a.
[(String, String)] -> String -> ContT a IO (String, String)
withOutput [(String, String)]
old_env) [String]
outputNames
let process :: CreateProcess
process = CreateProcess
cp { env :: Maybe [(String, String)]
env = [(String, String)] -> Maybe [(String, String)]
forall a. a -> Maybe a
Just ([(String, String)] -> Maybe [(String, String)])
-> [(String, String)] -> Maybe [(String, String)]
forall a b. (a -> b) -> a -> b
$ [(String, String)]
output_files [(String, String)] -> [(String, String)] -> [(String, String)]
forall a. [a] -> [a] -> [a]
++ [(String, String)]
-> Maybe [(String, String)] -> [(String, String)]
forall a. a -> Maybe a -> a
fromMaybe [(String, String)]
old_env (CreateProcess -> Maybe [(String, String)]
env CreateProcess
cp),
cwd :: Maybe String
cwd = String -> Maybe String
forall a. a -> Maybe a
Just String
workDir
}
let loggingConduit :: ConduitT ByteString c IO [String]
loggingConduit = ConduitT ByteString Text IO ()
forall (m :: * -> *). MonadThrow m => ConduitT ByteString Text m ()
C.decodeUtf8 ConduitT ByteString Text IO ()
-> ConduitT Text c IO [String] -> ConduitT ByteString c IO [String]
forall (m :: * -> *) a b c r.
Monad m =>
ConduitT a b m () -> ConduitT b c m r -> ConduitT a c m r
C..| ConduitT Text Text IO ()
forall (m :: * -> *). Monad m => ConduitT Text Text m ()
C.lines ConduitT Text Text IO ()
-> ConduitT Text c IO [String] -> ConduitT Text c IO [String]
forall (m :: * -> *) a b c r.
Monad m =>
ConduitT a b m () -> ConduitT b c m r -> ConduitT a c m r
C..| (Element Text -> Bool) -> ConduitT Text Text IO ()
forall seq (m :: * -> *).
(IsSequence seq, Monad m) =>
(Element seq -> Bool) -> ConduitT seq seq m ()
C.filterE (Element Text -> Element Text -> Bool
forall a. Eq a => a -> a -> Bool
/= Char
Element Text
'\r')
ConduitT Text Text IO ()
-> ConduitT Text c IO [String] -> ConduitT Text c IO [String]
forall (m :: * -> *) a b c r.
Monad m =>
ConduitT a b m () -> ConduitT b c m r -> ConduitT a c m r
C..| (Text -> String) -> ConduitT Text String IO ()
forall (m :: * -> *) a b. Monad m => (a -> b) -> ConduitT a b m ()
C.map Text -> String
T.unpack ConduitT Text String IO ()
-> ConduitT String c IO [String] -> ConduitT Text c IO [String]
forall (m :: * -> *) a b c r.
Monad m =>
ConduitT a b m () -> ConduitT b c m r -> ConduitT a c m r
C..| (String -> IO ()) -> ConduitT String String IO ()
forall (m :: * -> *) a. Monad m => (a -> m ()) -> ConduitT a a m ()
C.iterM (\String
msg -> LogAction IO (WithSeverity Log)
l LogAction IO (WithSeverity Log) -> WithSeverity Log -> IO ()
forall (m :: * -> *) msg. LogAction m msg -> msg -> m ()
<& String -> Log
LogProcessOutput String
msg Log -> Severity -> WithSeverity Log
forall msg. msg -> Severity -> WithSeverity msg
`WithSeverity` Severity
Debug) ConduitT String String IO ()
-> ConduitT String c IO [String] -> ConduitT String c IO [String]
forall (m :: * -> *) a b c r.
Monad m =>
ConduitT a b m () -> ConduitT b c m r -> ConduitT a c m r
C..| ConduitT String c IO [String]
forall (m :: * -> *) a o. Monad m => ConduitT a o m [a]
C.sinkList
IO ()
-> ContT
(ExitCode, [String], [String], [(String, Maybe [String])]) IO ()
forall a.
IO a
-> ContT
(ExitCode, [String], [String], [(String, Maybe [String])]) IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO ()
-> ContT
(ExitCode, [String], [String], [(String, Maybe [String])]) IO ())
-> IO ()
-> ContT
(ExitCode, [String], [String], [(String, Maybe [String])]) IO ()
forall a b. (a -> b) -> a -> b
$ LogAction IO (WithSeverity Log)
l LogAction IO (WithSeverity Log) -> WithSeverity Log -> IO ()
forall (m :: * -> *) msg. LogAction m msg -> msg -> m ()
<& CreateProcess -> Log
LogCreateProcessRun CreateProcess
process Log -> Severity -> WithSeverity Log
forall msg. msg -> Severity -> WithSeverity msg
`WithSeverity` Severity
Info
(ExitCode
ex, [String]
stdo, [String]
stde) <- IO (ExitCode, [String], [String])
-> ContT
(ExitCode, [String], [String], [(String, Maybe [String])])
IO
(ExitCode, [String], [String])
forall a.
IO a
-> ContT
(ExitCode, [String], [String], [(String, Maybe [String])]) IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (ExitCode, [String], [String])
-> ContT
(ExitCode, [String], [String], [(String, Maybe [String])])
IO
(ExitCode, [String], [String]))
-> IO (ExitCode, [String], [String])
-> ContT
(ExitCode, [String], [String], [(String, Maybe [String])])
IO
(ExitCode, [String], [String])
forall a b. (a -> b) -> a -> b
$ CreateProcess
-> ConduitT () ByteString IO ()
-> ConduitT ByteString Void IO [String]
-> ConduitT ByteString Void IO [String]
-> IO (ExitCode, [String], [String])
forall (m :: * -> *) a b.
MonadUnliftIO m =>
CreateProcess
-> ConduitT () ByteString m ()
-> ConduitT ByteString Void m a
-> ConduitT ByteString Void m b
-> m (ExitCode, a, b)
sourceProcessWithStreams CreateProcess
process ConduitT () ByteString IO ()
forall a. Monoid a => a
mempty ConduitT ByteString Void IO [String]
forall {c}. ConduitT ByteString c IO [String]
loggingConduit ConduitT ByteString Void IO [String]
forall {c}. ConduitT ByteString c IO [String]
loggingConduit
[(String, Maybe [String])]
res <- [(String, String)]
-> ((String, String)
-> ContT
(ExitCode, [String], [String], [(String, Maybe [String])])
IO
(String, Maybe [String]))
-> ContT
(ExitCode, [String], [String], [(String, Maybe [String])])
IO
[(String, Maybe [String])]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM [(String, String)]
output_files (((String, String)
-> ContT
(ExitCode, [String], [String], [(String, Maybe [String])])
IO
(String, Maybe [String]))
-> ContT
(ExitCode, [String], [String], [(String, Maybe [String])])
IO
[(String, Maybe [String])])
-> ((String, String)
-> ContT
(ExitCode, [String], [String], [(String, Maybe [String])])
IO
(String, Maybe [String]))
-> ContT
(ExitCode, [String], [String], [(String, Maybe [String])])
IO
[(String, Maybe [String])]
forall a b. (a -> b) -> a -> b
$ \(String
name,String
path) ->
IO (String, Maybe [String])
-> ContT
(ExitCode, [String], [String], [(String, Maybe [String])])
IO
(String, Maybe [String])
forall a.
IO a
-> ContT
(ExitCode, [String], [String], [(String, Maybe [String])]) IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (String, Maybe [String])
-> ContT
(ExitCode, [String], [String], [(String, Maybe [String])])
IO
(String, Maybe [String]))
-> IO (String, Maybe [String])
-> ContT
(ExitCode, [String], [String], [(String, Maybe [String])])
IO
(String, Maybe [String])
forall a b. (a -> b) -> a -> b
$ (String
name,) (Maybe [String] -> (String, Maybe [String]))
-> IO (Maybe [String]) -> IO (String, Maybe [String])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> IO (Maybe [String])
readOutput String
path
(ExitCode, [String], [String], [(String, Maybe [String])])
-> ContT
(ExitCode, [String], [String], [(String, Maybe [String])])
IO
(ExitCode, [String], [String], [(String, Maybe [String])])
forall a.
a
-> ContT
(ExitCode, [String], [String], [(String, Maybe [String])]) IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (ExitCode
ex, [String]
stdo, [String]
stde, [(String, Maybe [String])]
res)
where
readOutput :: FilePath -> IO (Maybe [String])
readOutput :: String -> IO (Maybe [String])
readOutput String
path = do
Bool
haveFile <- String -> IO Bool
doesFileExist String
path
if Bool
haveFile
then String
-> IOMode -> (Handle -> IO (Maybe [String])) -> IO (Maybe [String])
forall r. String -> IOMode -> (Handle -> IO r) -> IO r
withFile String
path IOMode
ReadMode ((Handle -> IO (Maybe [String])) -> IO (Maybe [String]))
-> (Handle -> IO (Maybe [String])) -> IO (Maybe [String])
forall a b. (a -> b) -> a -> b
$ \Handle
handle -> do
Handle -> BufferMode -> IO ()
hSetBuffering Handle
handle BufferMode
LineBuffering
!String
res <- String -> String
forall a. NFData a => a -> a
force (String -> String) -> IO String -> IO String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Handle -> IO String
hGetContents Handle
handle
Maybe [String] -> IO (Maybe [String])
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe [String] -> IO (Maybe [String]))
-> Maybe [String] -> IO (Maybe [String])
forall a b. (a -> b) -> a -> b
$ [String] -> Maybe [String]
forall a. a -> Maybe a
Just ([String] -> Maybe [String]) -> [String] -> Maybe [String]
forall a b. (a -> b) -> a -> b
$ String -> [String]
lines (String -> [String]) -> String -> [String]
forall a b. (a -> b) -> a -> b
$ (Char -> Bool) -> String -> String
forall a. (a -> Bool) -> [a] -> [a]
filter (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= Char
'\r') String
res
else
Maybe [String] -> IO (Maybe [String])
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe [String]
forall a. Maybe a
Nothing
withOutput :: [(String,String)] -> OutputName -> ContT a IO (OutputName, String)
withOutput :: forall a.
[(String, String)] -> String -> ContT a IO (String, String)
withOutput [(String, String)]
env' String
name =
case String -> [(String, String)] -> Maybe String
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup String
name [(String, String)]
env' of
Just file :: String
file@(Char
_:String
_) -> (((String, String) -> IO a) -> IO a) -> ContT a IO (String, String)
forall {k} (r :: k) (m :: k -> *) a.
((a -> m r) -> m r) -> ContT r m a
ContT ((((String, String) -> IO a) -> IO a)
-> ContT a IO (String, String))
-> (((String, String) -> IO a) -> IO a)
-> ContT a IO (String, String)
forall a b. (a -> b) -> a -> b
$ \(String, String) -> IO a
action -> do
String -> IO ()
removeFileIfExists String
file
(String, String) -> IO a
action (String
name, String
file)
Maybe String
_ -> (((String, String) -> IO a) -> IO a) -> ContT a IO (String, String)
forall {k} (r :: k) (m :: k -> *) a.
((a -> m r) -> m r) -> ContT r m a
ContT ((((String, String) -> IO a) -> IO a)
-> ContT a IO (String, String))
-> (((String, String) -> IO a) -> IO a)
-> ContT a IO (String, String)
forall a b. (a -> b) -> a -> b
$ \(String, String) -> IO a
action -> String -> (String -> Handle -> IO a) -> IO a
forall (m :: * -> *) a.
(MonadIO m, MonadMask m) =>
String -> (String -> Handle -> m a) -> m a
withSystemTempFile String
name ((String -> Handle -> IO a) -> IO a)
-> (String -> Handle -> IO a) -> IO a
forall a b. (a -> b) -> a -> b
$ \ String
file Handle
h -> do
Handle -> IO ()
hClose Handle
h
String -> IO ()
removeFileIfExists String
file
(String, String) -> IO a
action (String
name, String
file)
removeFileIfExists :: FilePath -> IO ()
removeFileIfExists :: String -> IO ()
removeFileIfExists String
f = do
Bool
yes <- String -> IO Bool
doesFileExist String
f
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
yes (String -> IO ()
removeFile String
f)
makeCradleResult :: (ExitCode, [String], FilePath, [String]) -> [FilePath] -> CradleLoadResult ComponentOptions
makeCradleResult :: (ExitCode, [String], String, [String])
-> [String] -> CradleLoadResult ComponentOptions
makeCradleResult (ExitCode
ex, [String]
err, String
componentDir, [String]
gopts) [String]
deps =
case ExitCode
ex of
ExitFailure Int
_ -> CradleError -> CradleLoadResult ComponentOptions
forall r. CradleError -> CradleLoadResult r
CradleFail ([String] -> ExitCode -> [String] -> CradleError
CradleError [String]
deps ExitCode
ex [String]
err)
ExitCode
_ ->
let compOpts :: ComponentOptions
compOpts = [String] -> String -> [String] -> ComponentOptions
ComponentOptions [String]
gopts String
componentDir [String]
deps
in ComponentOptions -> CradleLoadResult ComponentOptions
forall r. r -> CradleLoadResult r
CradleSuccess ComponentOptions
compOpts
runGhcCmdOnPath :: LogAction IO (WithSeverity Log) -> FilePath -> [String] -> IO (CradleLoadResult String)
runGhcCmdOnPath :: LogAction IO (WithSeverity Log)
-> String -> [String] -> IO (CradleLoadResult String)
runGhcCmdOnPath LogAction IO (WithSeverity Log)
l String
wdir [String]
args = LogAction IO (WithSeverity Log)
-> String
-> String
-> [String]
-> String
-> IO (CradleLoadResult String)
readProcessWithCwd LogAction IO (WithSeverity Log)
l String
wdir String
"ghc" [String]
args String
""
readProcessWithCwd :: LogAction IO (WithSeverity Log) -> FilePath -> FilePath -> [String] -> String -> IO (CradleLoadResult String)
readProcessWithCwd :: LogAction IO (WithSeverity Log)
-> String
-> String
-> [String]
-> String
-> IO (CradleLoadResult String)
readProcessWithCwd LogAction IO (WithSeverity Log)
l String
dir String
cmd [String]
args String
stdin = CradleLoadResultT IO String -> IO (CradleLoadResult String)
forall (m :: * -> *) a.
CradleLoadResultT m a -> m (CradleLoadResult a)
runCradleResultT (CradleLoadResultT IO String -> IO (CradleLoadResult String))
-> CradleLoadResultT IO String -> IO (CradleLoadResult String)
forall a b. (a -> b) -> a -> b
$ LogAction IO (WithSeverity Log)
-> String
-> String
-> [String]
-> String
-> CradleLoadResultT IO String
readProcessWithCwd_ LogAction IO (WithSeverity Log)
l String
dir String
cmd [String]
args String
stdin
readProcessWithCwd_ :: LogAction IO (WithSeverity Log) -> FilePath -> FilePath -> [String] -> String -> CradleLoadResultT IO String
readProcessWithCwd_ :: LogAction IO (WithSeverity Log)
-> String
-> String
-> [String]
-> String
-> CradleLoadResultT IO String
readProcessWithCwd_ LogAction IO (WithSeverity Log)
l String
dir String
cmd [String]
args String
stdin = do
[(String, String)]
cleanEnv <- IO [(String, String)] -> CradleLoadResultT IO [(String, String)]
forall a. IO a -> CradleLoadResultT IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO IO [(String, String)]
getCleanEnvironment
let createdProc' :: CreateProcess
createdProc' = (String -> [String] -> CreateProcess
proc String
cmd [String]
args) { cwd :: Maybe String
cwd = String -> Maybe String
forall a. a -> Maybe a
Just String
dir, env :: Maybe [(String, String)]
env = [(String, String)] -> Maybe [(String, String)]
forall a. a -> Maybe a
Just [(String, String)]
cleanEnv }
LogAction IO (WithSeverity Log)
-> CreateProcess -> String -> CradleLoadResultT IO String
readProcessWithCwd' LogAction IO (WithSeverity Log)
l CreateProcess
createdProc' String
stdin
readProcessWithCwd' :: LogAction IO (WithSeverity Log) -> CreateProcess -> String -> CradleLoadResultT IO String
readProcessWithCwd' :: LogAction IO (WithSeverity Log)
-> CreateProcess -> String -> CradleLoadResultT IO String
readProcessWithCwd' LogAction IO (WithSeverity Log)
l CreateProcess
createdProcess String
stdin = do
Maybe (ExitCode, String, String)
mResult <- IO (Maybe (ExitCode, String, String))
-> CradleLoadResultT IO (Maybe (ExitCode, String, String))
forall a. IO a -> CradleLoadResultT IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Maybe (ExitCode, String, String))
-> CradleLoadResultT IO (Maybe (ExitCode, String, String)))
-> IO (Maybe (ExitCode, String, String))
-> CradleLoadResultT IO (Maybe (ExitCode, String, String))
forall a b. (a -> b) -> a -> b
$ IO (ExitCode, String, String)
-> IO (Maybe (ExitCode, String, String))
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (IO (ExitCode, String, String)
-> IO (Maybe (ExitCode, String, String)))
-> IO (ExitCode, String, String)
-> IO (Maybe (ExitCode, String, String))
forall a b. (a -> b) -> a -> b
$ CreateProcess -> String -> IO (ExitCode, String, String)
readCreateProcessWithExitCode CreateProcess
createdProcess String
stdin
IO () -> CradleLoadResultT IO ()
forall a. IO a -> CradleLoadResultT IO a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> CradleLoadResultT IO ())
-> IO () -> CradleLoadResultT IO ()
forall a b. (a -> b) -> a -> b
$ LogAction IO (WithSeverity Log)
l LogAction IO (WithSeverity Log) -> WithSeverity Log -> IO ()
forall (m :: * -> *) msg. LogAction m msg -> msg -> m ()
<& CreateProcess -> Log
LogCreateProcessRun CreateProcess
createdProcess Log -> Severity -> WithSeverity Log
forall msg. msg -> Severity -> WithSeverity msg
`WithSeverity` Severity
Debug
let cmdString :: String
cmdString = CmdSpec -> String
prettyCmdSpec (CmdSpec -> String) -> CmdSpec -> String
forall a b. (a -> b) -> a -> b
$ CreateProcess -> CmdSpec
cmdspec CreateProcess
createdProcess
case Maybe (ExitCode, String, String)
mResult of
Just (ExitCode
ExitSuccess, String
stdo, String
_) -> String -> CradleLoadResultT IO String
forall a. a -> CradleLoadResultT IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure String
stdo
Just (ExitCode
exitCode, String
stdo, String
stde) -> CradleError -> CradleLoadResultT IO String
forall (m :: * -> *) a.
Monad m =>
CradleError -> CradleLoadResultT m a
throwCE (CradleError -> CradleLoadResultT IO String)
-> CradleError -> CradleLoadResultT IO String
forall a b. (a -> b) -> a -> b
$
[String] -> ExitCode -> [String] -> CradleError
CradleError [] ExitCode
exitCode ([String] -> CradleError) -> [String] -> CradleError
forall a b. (a -> b) -> a -> b
$
[String
"Error when calling " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
cmdString, String
stdo, String
stde] [String] -> [String] -> [String]
forall a. Semigroup a => a -> a -> a
<> CreateProcess -> [String]
prettyProcessEnv CreateProcess
createdProcess
Maybe (ExitCode, String, String)
Nothing -> CradleError -> CradleLoadResultT IO String
forall (m :: * -> *) a.
Monad m =>
CradleError -> CradleLoadResultT m a
throwCE (CradleError -> CradleLoadResultT IO String)
-> CradleError -> CradleLoadResultT IO String
forall a b. (a -> b) -> a -> b
$
[String] -> ExitCode -> [String] -> CradleError
CradleError [] ExitCode
ExitSuccess ([String] -> CradleError) -> [String] -> CradleError
forall a b. (a -> b) -> a -> b
$
[String
"Couldn't execute " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
cmdString] [String] -> [String] -> [String]
forall a. Semigroup a => a -> a -> a
<> CreateProcess -> [String]
prettyProcessEnv CreateProcess
createdProcess