module CabalHelper.Compiletime.Program.GHC where
import Control.Monad
import Control.Monad.Trans.Maybe
import Control.Monad.IO.Class
import Data.Char
import Data.List
import Data.Maybe
import Data.Version
import System.Exit
import System.FilePath
import System.Directory
import CabalHelper.Shared.Common
(parseVer, trim, appCacheDir, parsePkgId)
import CabalHelper.Compiletime.Types
import CabalHelper.Compiletime.Types.Cabal
( ResolvedCabalVersion, showResolvedCabalVersion, UnpackedCabalVersion
, unpackedToResolvedCabalVersion, CabalVersion'(..) )
import CabalHelper.Compiletime.Process
import CabalHelper.Compiletime.Log
data GhcPackageSource
= GPSAmbient
| GPSPackageDBs ![PackageDbDir]
| GPSPackageEnv !PackageEnvFile
data GhcInvocation = GhcInvocation
{ GhcInvocation -> FilePath
giOutDir :: !FilePath
, GhcInvocation -> FilePath
giOutput :: !FilePath
, GhcInvocation -> [FilePath]
giCPPOptions :: ![String]
, GhcInvocation -> GhcPackageSource
giPackageSource :: !GhcPackageSource
, GhcInvocation -> [FilePath]
giIncludeDirs :: ![FilePath]
, GhcInvocation -> Bool
giHideAllPackages :: !Bool
, GhcInvocation -> [FilePath]
giPackages :: ![String]
, GhcInvocation -> [FilePath]
giWarningFlags :: ![String]
, GhcInvocation -> [FilePath]
giInputs :: ![String]
}
newtype GhcVersion = GhcVersion { GhcVersion -> Version
unGhcVersion :: Version }
deriving (GhcVersion -> GhcVersion -> Bool
(GhcVersion -> GhcVersion -> Bool)
-> (GhcVersion -> GhcVersion -> Bool) -> Eq GhcVersion
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: GhcVersion -> GhcVersion -> Bool
$c/= :: GhcVersion -> GhcVersion -> Bool
== :: GhcVersion -> GhcVersion -> Bool
$c== :: GhcVersion -> GhcVersion -> Bool
Eq, Eq GhcVersion
Eq GhcVersion
-> (GhcVersion -> GhcVersion -> Ordering)
-> (GhcVersion -> GhcVersion -> Bool)
-> (GhcVersion -> GhcVersion -> Bool)
-> (GhcVersion -> GhcVersion -> Bool)
-> (GhcVersion -> GhcVersion -> Bool)
-> (GhcVersion -> GhcVersion -> GhcVersion)
-> (GhcVersion -> GhcVersion -> GhcVersion)
-> Ord GhcVersion
GhcVersion -> GhcVersion -> Bool
GhcVersion -> GhcVersion -> Ordering
GhcVersion -> GhcVersion -> GhcVersion
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: GhcVersion -> GhcVersion -> GhcVersion
$cmin :: GhcVersion -> GhcVersion -> GhcVersion
max :: GhcVersion -> GhcVersion -> GhcVersion
$cmax :: GhcVersion -> GhcVersion -> GhcVersion
>= :: GhcVersion -> GhcVersion -> Bool
$c>= :: GhcVersion -> GhcVersion -> Bool
> :: GhcVersion -> GhcVersion -> Bool
$c> :: GhcVersion -> GhcVersion -> Bool
<= :: GhcVersion -> GhcVersion -> Bool
$c<= :: GhcVersion -> GhcVersion -> Bool
< :: GhcVersion -> GhcVersion -> Bool
$c< :: GhcVersion -> GhcVersion -> Bool
compare :: GhcVersion -> GhcVersion -> Ordering
$ccompare :: GhcVersion -> GhcVersion -> Ordering
$cp1Ord :: Eq GhcVersion
Ord, ReadPrec [GhcVersion]
ReadPrec GhcVersion
Int -> ReadS GhcVersion
ReadS [GhcVersion]
(Int -> ReadS GhcVersion)
-> ReadS [GhcVersion]
-> ReadPrec GhcVersion
-> ReadPrec [GhcVersion]
-> Read GhcVersion
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [GhcVersion]
$creadListPrec :: ReadPrec [GhcVersion]
readPrec :: ReadPrec GhcVersion
$creadPrec :: ReadPrec GhcVersion
readList :: ReadS [GhcVersion]
$creadList :: ReadS [GhcVersion]
readsPrec :: Int -> ReadS GhcVersion
$creadsPrec :: Int -> ReadS GhcVersion
Read, Int -> GhcVersion -> ShowS
[GhcVersion] -> ShowS
GhcVersion -> FilePath
(Int -> GhcVersion -> ShowS)
-> (GhcVersion -> FilePath)
-> ([GhcVersion] -> ShowS)
-> Show GhcVersion
forall a.
(Int -> a -> ShowS) -> (a -> FilePath) -> ([a] -> ShowS) -> Show a
showList :: [GhcVersion] -> ShowS
$cshowList :: [GhcVersion] -> ShowS
show :: GhcVersion -> FilePath
$cshow :: GhcVersion -> FilePath
showsPrec :: Int -> GhcVersion -> ShowS
$cshowsPrec :: Int -> GhcVersion -> ShowS
Show)
showGhcVersion :: GhcVersion -> String
showGhcVersion :: GhcVersion -> FilePath
showGhcVersion (GhcVersion Version
v) = Version -> FilePath
showVersion Version
v
ghcVersion :: (Verbose, Progs) => IO GhcVersion
ghcVersion :: IO GhcVersion
ghcVersion = Version -> GhcVersion
GhcVersion (Version -> GhcVersion)
-> (FilePath -> Version) -> FilePath -> GhcVersion
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
FilePath -> Version
parseVer (FilePath -> Version) -> ShowS -> FilePath -> Version
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ShowS
trim (FilePath -> GhcVersion) -> IO FilePath -> IO GhcVersion
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Verbose => FilePath -> [FilePath] -> FilePath -> IO FilePath
FilePath -> [FilePath] -> FilePath -> IO FilePath
readProcess' (Programs -> FilePath
ghcProgram ?progs::Programs
Programs
?progs) [FilePath
"--numeric-version"] FilePath
""
ghcLibdir :: (Verbose, Progs) => IO FilePath
ghcLibdir :: IO FilePath
ghcLibdir = do
ShowS
trim ShowS -> IO FilePath -> IO FilePath
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Verbose => FilePath -> [FilePath] -> FilePath -> IO FilePath
FilePath -> [FilePath] -> FilePath -> IO FilePath
readProcess' (Programs -> FilePath
ghcProgram ?progs::Programs
Programs
?progs) [FilePath
"--print-libdir"] FilePath
""
ghcPkgVersion :: (Verbose, Progs) => IO Version
ghcPkgVersion :: IO Version
ghcPkgVersion =
FilePath -> Version
parseVer (FilePath -> Version) -> ShowS -> FilePath -> Version
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ShowS
trim ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> Bool) -> ShowS
forall a. (a -> Bool) -> [a] -> [a]
dropWhile (Bool -> Bool
not (Bool -> Bool) -> (Char -> Bool) -> Char -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Char -> Bool
isDigit)
(FilePath -> Version) -> IO FilePath -> IO Version
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Verbose => FilePath -> [FilePath] -> FilePath -> IO FilePath
FilePath -> [FilePath] -> FilePath -> IO FilePath
readProcess' (Programs -> FilePath
ghcPkgProgram ?progs::Programs
Programs
?progs) [FilePath
"--version"] FilePath
""
createPkgDb :: (Verbose, Progs) => UnpackedCabalVersion -> IO PackageDbDir
createPkgDb :: UnpackedCabalVersion -> IO PackageDbDir
createPkgDb UnpackedCabalVersion
cabalVer = do
db :: PackageDbDir
db@(PackageDbDir FilePath
db_path)
<- (Verbose, ?progs::Programs) =>
ResolvedCabalVersion -> IO PackageDbDir
ResolvedCabalVersion -> IO PackageDbDir
getPrivateCabalPkgDb (ResolvedCabalVersion -> IO PackageDbDir)
-> ResolvedCabalVersion -> IO PackageDbDir
forall a b. (a -> b) -> a -> b
$ UnpackedCabalVersion -> ResolvedCabalVersion
unpackedToResolvedCabalVersion UnpackedCabalVersion
cabalVer
Bool
exists <- FilePath -> IO Bool
doesDirectoryExist FilePath
db_path
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Bool -> Bool
not Bool
exists) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$
Verbose =>
Maybe FilePath
-> [(FilePath, EnvOverride)] -> FilePath -> [FilePath] -> IO ()
Maybe FilePath
-> [(FilePath, EnvOverride)] -> FilePath -> [FilePath] -> IO ()
callProcessStderr Maybe FilePath
forall a. Maybe a
Nothing [] (Programs -> FilePath
ghcPkgProgram ?progs::Programs
Programs
?progs) [FilePath
"init", FilePath
db_path]
PackageDbDir -> IO PackageDbDir
forall (m :: * -> *) a. Monad m => a -> m a
return PackageDbDir
db
getPrivateCabalPkgDb :: (Verbose, Progs) => ResolvedCabalVersion -> IO PackageDbDir
getPrivateCabalPkgDb :: ResolvedCabalVersion -> IO PackageDbDir
getPrivateCabalPkgDb ResolvedCabalVersion
cabalVer = do
FilePath
appdir <- IO FilePath
appCacheDir
GhcVersion
ghcVer <- IO GhcVersion
(Verbose, ?progs::Programs) => IO GhcVersion
ghcVersion
let db_path :: FilePath
db_path =
FilePath
appdir FilePath -> ShowS
</> FilePath
"ghc-" FilePath -> ShowS
forall a. [a] -> [a] -> [a]
++ GhcVersion -> FilePath
showGhcVersion GhcVersion
ghcVer FilePath -> ShowS
forall a. [a] -> [a] -> [a]
++ FilePath
".package-dbs"
FilePath -> ShowS
</> FilePath
"Cabal-" FilePath -> ShowS
forall a. [a] -> [a] -> [a]
++ ResolvedCabalVersion -> FilePath
showResolvedCabalVersion ResolvedCabalVersion
cabalVer
PackageDbDir -> IO PackageDbDir
forall (m :: * -> *) a. Monad m => a -> m a
return (PackageDbDir -> IO PackageDbDir)
-> PackageDbDir -> IO PackageDbDir
forall a b. (a -> b) -> a -> b
$ FilePath -> PackageDbDir
PackageDbDir FilePath
db_path
getPrivateCabalPkgEnv
:: Verbose => GhcVersion -> ResolvedCabalVersion -> IO PackageEnvFile
getPrivateCabalPkgEnv :: GhcVersion -> ResolvedCabalVersion -> IO PackageEnvFile
getPrivateCabalPkgEnv GhcVersion
ghcVer ResolvedCabalVersion
cabalVer = do
FilePath
appdir <- IO FilePath
appCacheDir
let env_path :: FilePath
env_path =
FilePath
appdir FilePath -> ShowS
</> FilePath
"ghc-" FilePath -> ShowS
forall a. [a] -> [a] -> [a]
++ GhcVersion -> FilePath
showGhcVersion GhcVersion
ghcVer FilePath -> ShowS
forall a. [a] -> [a] -> [a]
++ FilePath
".package-envs"
FilePath -> ShowS
</> FilePath
"Cabal-" FilePath -> ShowS
forall a. [a] -> [a] -> [a]
++ ResolvedCabalVersion -> FilePath
showResolvedCabalVersion ResolvedCabalVersion
cabalVer FilePath -> ShowS
forall a. [a] -> [a] -> [a]
++ FilePath
".package-env"
PackageEnvFile -> IO PackageEnvFile
forall (m :: * -> *) a. Monad m => a -> m a
return (PackageEnvFile -> IO PackageEnvFile)
-> PackageEnvFile -> IO PackageEnvFile
forall a b. (a -> b) -> a -> b
$ FilePath -> PackageEnvFile
PackageEnvFile FilePath
env_path
listCabalVersions
:: (Verbose, Progs) => Maybe PackageDbDir -> MaybeT IO [Version]
listCabalVersions :: Maybe PackageDbDir -> MaybeT IO [Version]
listCabalVersions Maybe PackageDbDir
mdb = do
let mdb_path :: Maybe FilePath
mdb_path = PackageDbDir -> FilePath
unPackageDbDir (PackageDbDir -> FilePath) -> Maybe PackageDbDir -> Maybe FilePath
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe PackageDbDir
mdb
Bool
exists <- Bool -> Maybe Bool -> Bool
forall a. a -> Maybe a -> a
fromMaybe Bool
True (Maybe Bool -> Bool) -> MaybeT IO (Maybe Bool) -> MaybeT IO Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
(FilePath -> MaybeT IO Bool)
-> Maybe FilePath -> MaybeT IO (Maybe Bool)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse (IO Bool -> MaybeT IO Bool
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Bool -> MaybeT IO Bool)
-> (FilePath -> IO Bool) -> FilePath -> MaybeT IO Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> IO Bool
doesDirectoryExist) Maybe FilePath
mdb_path
case Bool
exists of
Bool
True -> IO (Maybe [Version]) -> MaybeT IO [Version]
forall (m :: * -> *) a. m (Maybe a) -> MaybeT m a
MaybeT (IO (Maybe [Version]) -> MaybeT IO [Version])
-> IO (Maybe [Version]) -> MaybeT IO [Version]
forall a b. (a -> b) -> a -> b
$ FilePath -> IO (Maybe [Version]) -> IO (Maybe [Version])
forall a. Verbose => FilePath -> IO (Maybe a) -> IO (Maybe a)
logIOError FilePath
"listCabalVersions" (IO (Maybe [Version]) -> IO (Maybe [Version]))
-> IO (Maybe [Version]) -> IO (Maybe [Version])
forall a b. (a -> b) -> a -> b
$ [Version] -> Maybe [Version]
forall a. a -> Maybe a
Just ([Version] -> Maybe [Version])
-> IO [Version] -> IO (Maybe [Version])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> do
let mdbopt :: Maybe FilePath
mdbopt = (FilePath
"--package-conf="FilePath -> ShowS
forall a. [a] -> [a] -> [a]
++) ShowS -> Maybe FilePath -> Maybe FilePath
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe FilePath
mdb_path
args :: [FilePath]
args = [FilePath
"list", FilePath
"--simple-output", FilePath
"Cabal"] [FilePath] -> [FilePath] -> [FilePath]
forall a. [a] -> [a] -> [a]
++ Maybe FilePath -> [FilePath]
forall a. Maybe a -> [a]
maybeToList Maybe FilePath
mdbopt
[Maybe Version] -> [Version]
forall a. [Maybe a] -> [a]
catMaybes ([Maybe Version] -> [Version])
-> (FilePath -> [Maybe Version]) -> FilePath -> [Version]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (FilePath -> Maybe Version) -> [FilePath] -> [Maybe Version]
forall a b. (a -> b) -> [a] -> [b]
map (((FilePath, Version) -> Version)
-> Maybe (FilePath, Version) -> Maybe Version
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (FilePath, Version) -> Version
forall a b. (a, b) -> b
snd (Maybe (FilePath, Version) -> Maybe Version)
-> (FilePath -> Maybe (FilePath, Version))
-> FilePath
-> Maybe Version
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> Maybe (FilePath, Version)
parsePkgId) ([FilePath] -> [Maybe Version])
-> (FilePath -> [FilePath]) -> FilePath -> [Maybe Version]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> [FilePath]
words
(FilePath -> [Version]) -> IO FilePath -> IO [Version]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Verbose => FilePath -> [FilePath] -> FilePath -> IO FilePath
FilePath -> [FilePath] -> FilePath -> IO FilePath
readProcess' (Programs -> FilePath
ghcPkgProgram ?progs::Programs
Programs
?progs) [FilePath]
args FilePath
""
Bool
_ -> MaybeT IO [Version]
forall (m :: * -> *) a. MonadPlus m => m a
mzero
cabalVersionExistsInPkgDb
:: (Verbose, Progs) => CabalVersion' a -> PackageDbDir -> IO Bool
cabalVersionExistsInPkgDb :: CabalVersion' a -> PackageDbDir -> IO Bool
cabalVersionExistsInPkgDb CabalVersion' a
cabalVer db :: PackageDbDir
db@(PackageDbDir FilePath
db_path) = do
Bool -> Maybe Bool -> Bool
forall a. a -> Maybe a -> a
fromMaybe Bool
False (Maybe Bool -> Bool) -> IO (Maybe Bool) -> IO Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> MaybeT IO Bool -> IO (Maybe Bool)
forall (m :: * -> *) a. MaybeT m a -> m (Maybe a)
runMaybeT (do
[Version]
vers <- (Verbose, ?progs::Programs) =>
Maybe PackageDbDir -> MaybeT IO [Version]
Maybe PackageDbDir -> MaybeT IO [Version]
listCabalVersions (PackageDbDir -> Maybe PackageDbDir
forall a. a -> Maybe a
Just PackageDbDir
db)
Bool -> MaybeT IO Bool
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool -> MaybeT IO Bool) -> Bool -> MaybeT IO Bool
forall a b. (a -> b) -> a -> b
$
case (CabalVersion' a
cabalVer, [Version]
vers) of
(CabalVersion Version
ver, [Version]
_) -> Version
ver Version -> [Version] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Version]
vers
(CabalHEAD a
_, []) -> Bool
False
(CabalHEAD a
_, [Version
_headver]) -> Bool
True
(CabalHEAD a
_, [Version]
_) ->
FilePath -> Bool
forall a. HasCallStack => FilePath -> a
error (FilePath -> Bool) -> FilePath -> Bool
forall a b. (a -> b) -> a -> b
$ FilePath
msg FilePath -> ShowS
forall a. [a] -> [a] -> [a]
++ FilePath
db_path)
where
msg :: FilePath
msg = FilePath
"\
\Multiple Cabal versions in a HEAD package-db!\n\
\This shouldn't happen. However you can manually delete the following\n\
\directory to resolve this:\n "
invokeGhc :: Env => GhcInvocation -> IO (Either ExitCode FilePath)
invokeGhc :: GhcInvocation -> IO (Either ExitCode FilePath)
invokeGhc GhcInvocation {Bool
FilePath
[FilePath]
GhcPackageSource
giInputs :: [FilePath]
giWarningFlags :: [FilePath]
giPackages :: [FilePath]
giHideAllPackages :: Bool
giIncludeDirs :: [FilePath]
giPackageSource :: GhcPackageSource
giCPPOptions :: [FilePath]
giOutput :: FilePath
giOutDir :: FilePath
giInputs :: GhcInvocation -> [FilePath]
giWarningFlags :: GhcInvocation -> [FilePath]
giPackages :: GhcInvocation -> [FilePath]
giHideAllPackages :: GhcInvocation -> Bool
giIncludeDirs :: GhcInvocation -> [FilePath]
giPackageSource :: GhcInvocation -> GhcPackageSource
giCPPOptions :: GhcInvocation -> [FilePath]
giOutput :: GhcInvocation -> FilePath
giOutDir :: GhcInvocation -> FilePath
..} = do
FilePath
giOutDirAbs <- FilePath -> IO FilePath
makeAbsolute FilePath
giOutDir
FilePath
giOutputAbs <- FilePath -> IO FilePath
makeAbsolute FilePath
giOutput
[FilePath]
giIncludeDirsAbs <- (FilePath -> IO FilePath) -> [FilePath] -> IO [FilePath]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM FilePath -> IO FilePath
makeAbsolute [FilePath]
giIncludeDirs
[FilePath]
giInputsAbs <- (FilePath -> IO FilePath) -> [FilePath] -> IO [FilePath]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM FilePath -> IO FilePath
makeAbsolute [FilePath]
giInputs
let eos :: [(FilePath, EnvOverride)]
eos = [(FilePath
"GHC_ENVIRONMENT", EnvOverride
EnvUnset), (FilePath
"GHC_PACKAGE_PATH", EnvOverride
EnvUnset)]
ExitCode
rv <- Verbose =>
Maybe FilePath
-> [(FilePath, EnvOverride)]
-> FilePath
-> [FilePath]
-> IO ExitCode
Maybe FilePath
-> [(FilePath, EnvOverride)]
-> FilePath
-> [FilePath]
-> IO ExitCode
callProcessStderr' (FilePath -> Maybe FilePath
forall a. a -> Maybe a
Just FilePath
"/") [(FilePath, EnvOverride)]
eos (Programs -> FilePath
ghcProgram ?progs::Programs
Programs
?progs) ([FilePath] -> IO ExitCode) -> [FilePath] -> IO ExitCode
forall a b. (a -> b) -> a -> b
$ [[FilePath]] -> [FilePath]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
[ [ FilePath
"-outputdir", FilePath
giOutDirAbs
, FilePath
"-o", FilePath
giOutputAbs
]
, ShowS -> [FilePath] -> [FilePath]
forall a b. (a -> b) -> [a] -> [b]
map (FilePath
"-optP"FilePath -> ShowS
forall a. [a] -> [a] -> [a]
++) [FilePath]
giCPPOptions
, if Bool
giHideAllPackages then [FilePath
"-hide-all-packages"] else []
, let packageFlags :: [FilePath]
packageFlags = (FilePath -> [FilePath]) -> [FilePath] -> [FilePath]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (\FilePath
p -> [FilePath
"-package", FilePath
p]) [FilePath]
giPackages in
case GhcPackageSource
giPackageSource of
GhcPackageSource
GPSAmbient -> [FilePath]
packageFlags
GPSPackageDBs [PackageDbDir]
dbs -> [[FilePath]] -> [FilePath]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
[ ShowS -> [FilePath] -> [FilePath]
forall a b. (a -> b) -> [a] -> [b]
map (FilePath
"-package-conf="FilePath -> ShowS
forall a. [a] -> [a] -> [a]
++) ([FilePath] -> [FilePath]) -> [FilePath] -> [FilePath]
forall a b. (a -> b) -> a -> b
$ PackageDbDir -> FilePath
unPackageDbDir (PackageDbDir -> FilePath) -> [PackageDbDir] -> [FilePath]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [PackageDbDir]
dbs
, [FilePath]
packageFlags
]
GPSPackageEnv PackageEnvFile
env -> [ FilePath
"-package-env=" FilePath -> ShowS
forall a. [a] -> [a] -> [a]
++ PackageEnvFile -> FilePath
unPackageEnvFile PackageEnvFile
env ]
, ShowS -> [FilePath] -> [FilePath]
forall a b. (a -> b) -> [a] -> [b]
map (FilePath
"-i"FilePath -> ShowS
forall a. [a] -> [a] -> [a]
++) ([FilePath] -> [FilePath]) -> [FilePath] -> [FilePath]
forall a b. (a -> b) -> a -> b
$ [FilePath] -> [FilePath]
forall a. Eq a => [a] -> [a]
nub ([FilePath] -> [FilePath]) -> [FilePath] -> [FilePath]
forall a b. (a -> b) -> a -> b
$ FilePath
"" FilePath -> [FilePath] -> [FilePath]
forall a. a -> [a] -> [a]
: [FilePath]
giIncludeDirsAbs
, [FilePath]
giWarningFlags
, [FilePath
"--make"]
, [FilePath]
giInputsAbs
]
Either ExitCode FilePath -> IO (Either ExitCode FilePath)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either ExitCode FilePath -> IO (Either ExitCode FilePath))
-> Either ExitCode FilePath -> IO (Either ExitCode FilePath)
forall a b. (a -> b) -> a -> b
$
case ExitCode
rv of
ExitCode
ExitSuccess -> FilePath -> Either ExitCode FilePath
forall a b. b -> Either a b
Right FilePath
giOutput
e :: ExitCode
e@(ExitFailure Int
_) -> ExitCode -> Either ExitCode FilePath
forall a b. a -> Either a b
Left ExitCode
e