{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE ViewPatterns #-}
module Ormolu.Utils.Cabal
( CabalInfo (..),
defaultCabalInfo,
PackageName,
unPackageName,
Extension (..),
getCabalInfoForSourceFile,
findCabalFile,
parseCabalInfo,
)
where
import Control.Exception
import Control.Monad.IO.Class
import qualified Data.ByteString as B
import Data.Map.Lazy (Map)
import qualified Data.Map.Lazy as M
import Data.Maybe (maybeToList)
import Data.Set (Set)
import qualified Data.Set as Set
import qualified Distribution.ModuleName as ModuleName
import Distribution.PackageDescription
import Distribution.PackageDescription.Parsec
import qualified Distribution.Types.CondTree as CT
import Distribution.Utils.Path (getSymbolicPath)
import Language.Haskell.Extension
import Ormolu.Config
import Ormolu.Exception
import System.Directory
import System.FilePath
import System.IO (hPutStrLn, stderr)
import System.IO.Error (isDoesNotExistError)
data CabalInfo = CabalInfo
{
CabalInfo -> Maybe String
ciPackageName :: !(Maybe String),
CabalInfo -> [DynOption]
ciDynOpts :: ![DynOption],
CabalInfo -> Set String
ciDependencies :: !(Set String),
CabalInfo -> Maybe String
ciCabalFilePath :: !(Maybe FilePath)
}
deriving (CabalInfo -> CabalInfo -> Bool
(CabalInfo -> CabalInfo -> Bool)
-> (CabalInfo -> CabalInfo -> Bool) -> Eq CabalInfo
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: CabalInfo -> CabalInfo -> Bool
$c/= :: CabalInfo -> CabalInfo -> Bool
== :: CabalInfo -> CabalInfo -> Bool
$c== :: CabalInfo -> CabalInfo -> Bool
Eq, Int -> CabalInfo -> ShowS
[CabalInfo] -> ShowS
CabalInfo -> String
(Int -> CabalInfo -> ShowS)
-> (CabalInfo -> String)
-> ([CabalInfo] -> ShowS)
-> Show CabalInfo
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [CabalInfo] -> ShowS
$cshowList :: [CabalInfo] -> ShowS
show :: CabalInfo -> String
$cshow :: CabalInfo -> String
showsPrec :: Int -> CabalInfo -> ShowS
$cshowsPrec :: Int -> CabalInfo -> ShowS
Show)
defaultCabalInfo :: CabalInfo
defaultCabalInfo :: CabalInfo
defaultCabalInfo =
CabalInfo :: Maybe String
-> [DynOption] -> Set String -> Maybe String -> CabalInfo
CabalInfo
{ ciPackageName :: Maybe String
ciPackageName = Maybe String
forall a. Maybe a
Nothing,
ciDynOpts :: [DynOption]
ciDynOpts = [],
ciDependencies :: Set String
ciDependencies = Set String
forall a. Set a
Set.empty,
ciCabalFilePath :: Maybe String
ciCabalFilePath = Maybe String
forall a. Maybe a
Nothing
}
getCabalInfoForSourceFile ::
MonadIO m =>
FilePath ->
m CabalInfo
getCabalInfoForSourceFile :: String -> m CabalInfo
getCabalInfoForSourceFile String
sourceFile = IO CabalInfo -> m CabalInfo
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO CabalInfo -> m CabalInfo) -> IO CabalInfo -> m CabalInfo
forall a b. (a -> b) -> a -> b
$ do
String -> IO (Maybe String)
forall (m :: * -> *). MonadIO m => String -> m (Maybe String)
findCabalFile String
sourceFile IO (Maybe String) -> (Maybe String -> IO CabalInfo) -> IO CabalInfo
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Just String
cabalFile -> String -> String -> IO CabalInfo
forall (m :: * -> *). MonadIO m => String -> String -> m CabalInfo
parseCabalInfo String
cabalFile String
sourceFile
Maybe String
Nothing -> do
Handle -> String -> IO ()
hPutStrLn Handle
stderr (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"Could not find a .cabal file for " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
sourceFile
CabalInfo -> IO CabalInfo
forall (m :: * -> *) a. Monad m => a -> m a
return CabalInfo
defaultCabalInfo
findCabalFile ::
MonadIO m =>
FilePath ->
m (Maybe FilePath)
findCabalFile :: String -> m (Maybe String)
findCabalFile String
sourceFile = IO (Maybe String) -> m (Maybe String)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Maybe String) -> m (Maybe String))
-> IO (Maybe String) -> m (Maybe String)
forall a b. (a -> b) -> a -> b
$ do
String
parentDir <- ShowS
takeDirectory ShowS -> IO String -> IO String
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> IO String
makeAbsolute String
sourceFile
[String]
dirEntries <-
String -> IO [String]
listDirectory String
parentDir IO [String] -> (IOError -> IO [String]) -> IO [String]
forall e a. Exception e => IO a -> (e -> IO a) -> IO a
`catch` \case
(IOError -> Bool
isDoesNotExistError -> Bool
True) -> [String] -> IO [String]
forall (f :: * -> *) a. Applicative f => a -> f a
pure []
IOError
e -> IOError -> IO [String]
forall e a. Exception e => e -> IO a
throwIO IOError
e
let findDotCabal :: [String] -> IO (Maybe String)
findDotCabal = \case
[] -> Maybe String -> IO (Maybe String)
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe String
forall a. Maybe a
Nothing
String
e : [String]
es
| ShowS
takeExtension String
e String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
".cabal" ->
String -> IO Bool
doesFileExist (String
parentDir String -> ShowS
</> String
e) IO Bool -> (Bool -> IO (Maybe String)) -> IO (Maybe String)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Bool
True -> Maybe String -> IO (Maybe String)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (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
e
Bool
False -> [String] -> IO (Maybe String)
findDotCabal [String]
es
String
_ : [String]
es -> [String] -> IO (Maybe String)
findDotCabal [String]
es
[String] -> IO (Maybe String)
findDotCabal [String]
dirEntries IO (Maybe String)
-> (Maybe String -> IO (Maybe String)) -> IO (Maybe String)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Just String
cabalFile -> Maybe String -> IO (Maybe String)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe String -> IO (Maybe String))
-> (String -> Maybe String) -> String -> IO (Maybe String)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Maybe String
forall a. a -> Maybe a
Just (String -> IO (Maybe String)) -> String -> IO (Maybe String)
forall a b. (a -> b) -> a -> b
$ String
parentDir String -> ShowS
</> String
cabalFile
Maybe String
Nothing ->
if String -> Bool
isDrive String
parentDir
then Maybe String -> IO (Maybe String)
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe String
forall a. Maybe a
Nothing
else String -> IO (Maybe String)
forall (m :: * -> *). MonadIO m => String -> m (Maybe String)
findCabalFile String
parentDir
parseCabalInfo ::
MonadIO m =>
FilePath ->
FilePath ->
m CabalInfo
parseCabalInfo :: String -> String -> m CabalInfo
parseCabalInfo String
cabalFileAsGiven String
sourceFileAsGiven = IO CabalInfo -> m CabalInfo
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO CabalInfo -> m CabalInfo) -> IO CabalInfo -> m CabalInfo
forall a b. (a -> b) -> a -> b
$ do
String
cabalFile <- String -> IO String
makeAbsolute String
cabalFileAsGiven
String
sourceFileAbs <- String -> IO String
makeAbsolute String
sourceFileAsGiven
ByteString
cabalFileBs <- String -> IO ByteString
B.readFile String
cabalFile
GenericPackageDescription
genericPackageDescription <-
case ByteString -> Maybe GenericPackageDescription
parseGenericPackageDescriptionMaybe ByteString
cabalFileBs of
Just GenericPackageDescription
gpd -> GenericPackageDescription -> IO GenericPackageDescription
forall (f :: * -> *) a. Applicative f => a -> f a
pure GenericPackageDescription
gpd
Maybe GenericPackageDescription
Nothing -> OrmoluException -> IO GenericPackageDescription
forall e a. Exception e => e -> IO a
throwIO (String -> OrmoluException
OrmoluCabalFileParsingFailed String
cabalFile)
([DynOption]
dynOpts, [String]
dependencies) <- do
let extMap :: Map String ([DynOption], [String])
extMap = String
-> GenericPackageDescription -> Map String ([DynOption], [String])
getExtensionAndDepsMap String
cabalFile GenericPackageDescription
genericPackageDescription
case String
-> Map String ([DynOption], [String])
-> Maybe ([DynOption], [String])
forall k a. Ord k => k -> Map k a -> Maybe a
M.lookup (ShowS
dropExtensions String
sourceFileAbs) Map String ([DynOption], [String])
extMap of
Just ([DynOption], [String])
exts -> ([DynOption], [String]) -> IO ([DynOption], [String])
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([DynOption], [String])
exts
Maybe ([DynOption], [String])
Nothing -> do
String
relativeCabalFile <- String -> IO String
makeRelativeToCurrentDirectory String
cabalFile
Handle -> String -> IO ()
hPutStrLn Handle
stderr (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$
String
"Found .cabal file "
String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
relativeCabalFile
String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
", but it did not mention "
String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
sourceFileAsGiven
([DynOption], [String]) -> IO ([DynOption], [String])
forall (m :: * -> *) a. Monad m => a -> m a
return ([], [])
let pdesc :: PackageDescription
pdesc = GenericPackageDescription -> PackageDescription
packageDescription GenericPackageDescription
genericPackageDescription
packageName :: String
packageName = (PackageName -> String
unPackageName (PackageName -> String)
-> (PackageDescription -> PackageName)
-> PackageDescription
-> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PackageIdentifier -> PackageName
pkgName (PackageIdentifier -> PackageName)
-> (PackageDescription -> PackageIdentifier)
-> PackageDescription
-> PackageName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PackageDescription -> PackageIdentifier
package) PackageDescription
pdesc
CabalInfo -> IO CabalInfo
forall (m :: * -> *) a. Monad m => a -> m a
return
CabalInfo :: Maybe String
-> [DynOption] -> Set String -> Maybe String -> CabalInfo
CabalInfo
{ ciPackageName :: Maybe String
ciPackageName = String -> Maybe String
forall a. a -> Maybe a
Just String
packageName,
ciDynOpts :: [DynOption]
ciDynOpts = [DynOption]
dynOpts,
ciDependencies :: Set String
ciDependencies = [String] -> Set String
forall a. Ord a => [a] -> Set a
Set.fromList [String]
dependencies,
ciCabalFilePath :: Maybe String
ciCabalFilePath = String -> Maybe String
forall a. a -> Maybe a
Just String
cabalFile
}
getExtensionAndDepsMap ::
FilePath ->
GenericPackageDescription ->
Map FilePath ([DynOption], [String])
getExtensionAndDepsMap :: String
-> GenericPackageDescription -> Map String ([DynOption], [String])
getExtensionAndDepsMap String
cabalFile GenericPackageDescription {[(UnqualComponentName, CondTree ConfVar [Dependency] Benchmark)]
[(UnqualComponentName, CondTree ConfVar [Dependency] Executable)]
[(UnqualComponentName, CondTree ConfVar [Dependency] ForeignLib)]
[(UnqualComponentName, CondTree ConfVar [Dependency] Library)]
[(UnqualComponentName, CondTree ConfVar [Dependency] TestSuite)]
[PackageFlag]
Maybe Version
Maybe (CondTree ConfVar [Dependency] Library)
PackageDescription
gpdScannedVersion :: GenericPackageDescription -> Maybe Version
genPackageFlags :: GenericPackageDescription -> [PackageFlag]
condLibrary :: GenericPackageDescription
-> Maybe (CondTree ConfVar [Dependency] Library)
condSubLibraries :: GenericPackageDescription
-> [(UnqualComponentName, CondTree ConfVar [Dependency] Library)]
condForeignLibs :: GenericPackageDescription
-> [(UnqualComponentName,
CondTree ConfVar [Dependency] ForeignLib)]
condExecutables :: GenericPackageDescription
-> [(UnqualComponentName,
CondTree ConfVar [Dependency] Executable)]
condTestSuites :: GenericPackageDescription
-> [(UnqualComponentName, CondTree ConfVar [Dependency] TestSuite)]
condBenchmarks :: GenericPackageDescription
-> [(UnqualComponentName, CondTree ConfVar [Dependency] Benchmark)]
condBenchmarks :: [(UnqualComponentName, CondTree ConfVar [Dependency] Benchmark)]
condTestSuites :: [(UnqualComponentName, CondTree ConfVar [Dependency] TestSuite)]
condExecutables :: [(UnqualComponentName, CondTree ConfVar [Dependency] Executable)]
condForeignLibs :: [(UnqualComponentName, CondTree ConfVar [Dependency] ForeignLib)]
condSubLibraries :: [(UnqualComponentName, CondTree ConfVar [Dependency] Library)]
condLibrary :: Maybe (CondTree ConfVar [Dependency] Library)
genPackageFlags :: [PackageFlag]
gpdScannedVersion :: Maybe Version
packageDescription :: PackageDescription
packageDescription :: GenericPackageDescription -> PackageDescription
..} =
[Map String ([DynOption], [String])]
-> Map String ([DynOption], [String])
forall (f :: * -> *) k a.
(Foldable f, Ord k) =>
f (Map k a) -> Map k a
M.unions ([Map String ([DynOption], [String])]
-> Map String ([DynOption], [String]))
-> ([[Map String ([DynOption], [String])]]
-> [Map String ([DynOption], [String])])
-> [[Map String ([DynOption], [String])]]
-> Map String ([DynOption], [String])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [[Map String ([DynOption], [String])]]
-> [Map String ([DynOption], [String])]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[Map String ([DynOption], [String])]]
-> Map String ([DynOption], [String]))
-> [[Map String ([DynOption], [String])]]
-> Map String ([DynOption], [String])
forall a b. (a -> b) -> a -> b
$
[ (Library -> ([String], ([DynOption], [String])))
-> CondTree ConfVar [Dependency] Library
-> Map String ([DynOption], [String])
forall k a b a v.
(Ord k, Semigroup a, Semigroup b) =>
(a -> ([k], a)) -> CondTree v b a -> Map k a
buildMap Library -> ([String], ([DynOption], [String]))
extractFromLibrary (CondTree ConfVar [Dependency] Library
-> Map String ([DynOption], [String]))
-> [CondTree ConfVar [Dependency] Library]
-> [Map String ([DynOption], [String])]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [CondTree ConfVar [Dependency] Library]
lib [CondTree ConfVar [Dependency] Library]
-> [CondTree ConfVar [Dependency] Library]
-> [CondTree ConfVar [Dependency] Library]
forall a. [a] -> [a] -> [a]
++ [CondTree ConfVar [Dependency] Library]
sublibs,
(Executable -> ([String], ([DynOption], [String])))
-> CondTree ConfVar [Dependency] Executable
-> Map String ([DynOption], [String])
forall k a b a v.
(Ord k, Semigroup a, Semigroup b) =>
(a -> ([k], a)) -> CondTree v b a -> Map k a
buildMap Executable -> ([String], ([DynOption], [String]))
extractFromExecutable (CondTree ConfVar [Dependency] Executable
-> Map String ([DynOption], [String]))
-> ((UnqualComponentName, CondTree ConfVar [Dependency] Executable)
-> CondTree ConfVar [Dependency] Executable)
-> (UnqualComponentName, CondTree ConfVar [Dependency] Executable)
-> Map String ([DynOption], [String])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (UnqualComponentName, CondTree ConfVar [Dependency] Executable)
-> CondTree ConfVar [Dependency] Executable
forall a b. (a, b) -> b
snd ((UnqualComponentName, CondTree ConfVar [Dependency] Executable)
-> Map String ([DynOption], [String]))
-> [(UnqualComponentName,
CondTree ConfVar [Dependency] Executable)]
-> [Map String ([DynOption], [String])]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [(UnqualComponentName, CondTree ConfVar [Dependency] Executable)]
condExecutables,
(TestSuite -> ([String], ([DynOption], [String])))
-> CondTree ConfVar [Dependency] TestSuite
-> Map String ([DynOption], [String])
forall k a b a v.
(Ord k, Semigroup a, Semigroup b) =>
(a -> ([k], a)) -> CondTree v b a -> Map k a
buildMap TestSuite -> ([String], ([DynOption], [String]))
extractFromTestSuite (CondTree ConfVar [Dependency] TestSuite
-> Map String ([DynOption], [String]))
-> ((UnqualComponentName, CondTree ConfVar [Dependency] TestSuite)
-> CondTree ConfVar [Dependency] TestSuite)
-> (UnqualComponentName, CondTree ConfVar [Dependency] TestSuite)
-> Map String ([DynOption], [String])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (UnqualComponentName, CondTree ConfVar [Dependency] TestSuite)
-> CondTree ConfVar [Dependency] TestSuite
forall a b. (a, b) -> b
snd ((UnqualComponentName, CondTree ConfVar [Dependency] TestSuite)
-> Map String ([DynOption], [String]))
-> [(UnqualComponentName, CondTree ConfVar [Dependency] TestSuite)]
-> [Map String ([DynOption], [String])]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [(UnqualComponentName, CondTree ConfVar [Dependency] TestSuite)]
condTestSuites,
(Benchmark -> ([String], ([DynOption], [String])))
-> CondTree ConfVar [Dependency] Benchmark
-> Map String ([DynOption], [String])
forall k a b a v.
(Ord k, Semigroup a, Semigroup b) =>
(a -> ([k], a)) -> CondTree v b a -> Map k a
buildMap Benchmark -> ([String], ([DynOption], [String]))
extractFromBenchmark (CondTree ConfVar [Dependency] Benchmark
-> Map String ([DynOption], [String]))
-> ((UnqualComponentName, CondTree ConfVar [Dependency] Benchmark)
-> CondTree ConfVar [Dependency] Benchmark)
-> (UnqualComponentName, CondTree ConfVar [Dependency] Benchmark)
-> Map String ([DynOption], [String])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (UnqualComponentName, CondTree ConfVar [Dependency] Benchmark)
-> CondTree ConfVar [Dependency] Benchmark
forall a b. (a, b) -> b
snd ((UnqualComponentName, CondTree ConfVar [Dependency] Benchmark)
-> Map String ([DynOption], [String]))
-> [(UnqualComponentName, CondTree ConfVar [Dependency] Benchmark)]
-> [Map String ([DynOption], [String])]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [(UnqualComponentName, CondTree ConfVar [Dependency] Benchmark)]
condBenchmarks
]
where
lib :: [CondTree ConfVar [Dependency] Library]
lib = Maybe (CondTree ConfVar [Dependency] Library)
-> [CondTree ConfVar [Dependency] Library]
forall a. Maybe a -> [a]
maybeToList Maybe (CondTree ConfVar [Dependency] Library)
condLibrary
sublibs :: [CondTree ConfVar [Dependency] Library]
sublibs = (UnqualComponentName, CondTree ConfVar [Dependency] Library)
-> CondTree ConfVar [Dependency] Library
forall a b. (a, b) -> b
snd ((UnqualComponentName, CondTree ConfVar [Dependency] Library)
-> CondTree ConfVar [Dependency] Library)
-> [(UnqualComponentName, CondTree ConfVar [Dependency] Library)]
-> [CondTree ConfVar [Dependency] Library]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [(UnqualComponentName, CondTree ConfVar [Dependency] Library)]
condSubLibraries
buildMap :: (a -> ([k], a)) -> CondTree v b a -> Map k a
buildMap a -> ([k], a)
f CondTree v b a
a = [(k, a)] -> Map k a
forall k a. Ord k => [(k, a)] -> Map k a
M.fromList ((,a
extsAndDeps) (k -> (k, a)) -> [k] -> [(k, a)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [k]
files)
where
(a
mergedA, b
_) = CondTree v b a -> (a, b)
forall a c v.
(Semigroup a, Semigroup c) =>
CondTree v c a -> (a, c)
CT.ignoreConditions CondTree v b a
a
([k]
files, a
extsAndDeps) = a -> ([k], a)
f a
mergedA
extractFromBuildInfo :: [String] -> BuildInfo -> ([String], ([DynOption], [String]))
extractFromBuildInfo [String]
extraModules BuildInfo {Bool
[String]
[(String, String)]
[Language]
[Extension]
[Dependency]
[ExeDependency]
[LegacyExeDependency]
[Mixin]
[ModuleName]
[PkgconfigDependency]
[SymbolicPath PackageDir SourceDir]
Maybe Language
PerCompilerFlavor [String]
buildable :: BuildInfo -> Bool
buildTools :: BuildInfo -> [LegacyExeDependency]
buildToolDepends :: BuildInfo -> [ExeDependency]
cppOptions :: BuildInfo -> [String]
asmOptions :: BuildInfo -> [String]
cmmOptions :: BuildInfo -> [String]
ccOptions :: BuildInfo -> [String]
cxxOptions :: BuildInfo -> [String]
ldOptions :: BuildInfo -> [String]
hsc2hsOptions :: BuildInfo -> [String]
pkgconfigDepends :: BuildInfo -> [PkgconfigDependency]
frameworks :: BuildInfo -> [String]
extraFrameworkDirs :: BuildInfo -> [String]
asmSources :: BuildInfo -> [String]
cmmSources :: BuildInfo -> [String]
cSources :: BuildInfo -> [String]
cxxSources :: BuildInfo -> [String]
jsSources :: BuildInfo -> [String]
hsSourceDirs :: BuildInfo -> [SymbolicPath PackageDir SourceDir]
otherModules :: BuildInfo -> [ModuleName]
virtualModules :: BuildInfo -> [ModuleName]
autogenModules :: BuildInfo -> [ModuleName]
defaultLanguage :: BuildInfo -> Maybe Language
otherLanguages :: BuildInfo -> [Language]
defaultExtensions :: BuildInfo -> [Extension]
otherExtensions :: BuildInfo -> [Extension]
oldExtensions :: BuildInfo -> [Extension]
extraLibs :: BuildInfo -> [String]
extraGHCiLibs :: BuildInfo -> [String]
extraBundledLibs :: BuildInfo -> [String]
extraLibFlavours :: BuildInfo -> [String]
extraDynLibFlavours :: BuildInfo -> [String]
extraLibDirs :: BuildInfo -> [String]
includeDirs :: BuildInfo -> [String]
includes :: BuildInfo -> [String]
autogenIncludes :: BuildInfo -> [String]
installIncludes :: BuildInfo -> [String]
options :: BuildInfo -> PerCompilerFlavor [String]
profOptions :: BuildInfo -> PerCompilerFlavor [String]
sharedOptions :: BuildInfo -> PerCompilerFlavor [String]
staticOptions :: BuildInfo -> PerCompilerFlavor [String]
customFieldsBI :: BuildInfo -> [(String, String)]
targetBuildDepends :: BuildInfo -> [Dependency]
mixins :: BuildInfo -> [Mixin]
mixins :: [Mixin]
targetBuildDepends :: [Dependency]
customFieldsBI :: [(String, String)]
staticOptions :: PerCompilerFlavor [String]
sharedOptions :: PerCompilerFlavor [String]
profOptions :: PerCompilerFlavor [String]
options :: PerCompilerFlavor [String]
installIncludes :: [String]
autogenIncludes :: [String]
includes :: [String]
includeDirs :: [String]
extraLibDirs :: [String]
extraDynLibFlavours :: [String]
extraLibFlavours :: [String]
extraBundledLibs :: [String]
extraGHCiLibs :: [String]
extraLibs :: [String]
oldExtensions :: [Extension]
otherExtensions :: [Extension]
defaultExtensions :: [Extension]
otherLanguages :: [Language]
defaultLanguage :: Maybe Language
autogenModules :: [ModuleName]
virtualModules :: [ModuleName]
otherModules :: [ModuleName]
hsSourceDirs :: [SymbolicPath PackageDir SourceDir]
jsSources :: [String]
cxxSources :: [String]
cSources :: [String]
cmmSources :: [String]
asmSources :: [String]
extraFrameworkDirs :: [String]
frameworks :: [String]
pkgconfigDepends :: [PkgconfigDependency]
hsc2hsOptions :: [String]
ldOptions :: [String]
cxxOptions :: [String]
ccOptions :: [String]
cmmOptions :: [String]
asmOptions :: [String]
cppOptions :: [String]
buildToolDepends :: [ExeDependency]
buildTools :: [LegacyExeDependency]
buildable :: Bool
..} = (,([DynOption]
exts, [String]
deps)) ([String] -> ([String], ([DynOption], [String])))
-> [String] -> ([String], ([DynOption], [String]))
forall a b. (a -> b) -> a -> b
$ do
String
m <- [String]
extraModules [String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ (ModuleName -> String
ModuleName.toFilePath (ModuleName -> String) -> [ModuleName] -> [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [ModuleName]
otherModules)
(ShowS
takeDirectory String
cabalFile String -> ShowS
</>) ShowS -> [String] -> [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> [String]
prependSrcDirs (ShowS
dropExtensions String
m)
where
prependSrcDirs :: String -> [String]
prependSrcDirs String
f
| [SymbolicPath PackageDir SourceDir] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [SymbolicPath PackageDir SourceDir]
hsSourceDirs = [String
f]
| Bool
otherwise = (String -> ShowS
</> String
f) ShowS
-> (SymbolicPath PackageDir SourceDir -> String)
-> SymbolicPath PackageDir SourceDir
-> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SymbolicPath PackageDir SourceDir -> String
forall from to. SymbolicPath from to -> String
getSymbolicPath (SymbolicPath PackageDir SourceDir -> String)
-> [SymbolicPath PackageDir SourceDir] -> [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [SymbolicPath PackageDir SourceDir]
hsSourceDirs
deps :: [String]
deps = PackageName -> String
unPackageName (PackageName -> String)
-> (Dependency -> PackageName) -> Dependency -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Dependency -> PackageName
depPkgName (Dependency -> String) -> [Dependency] -> [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Dependency]
targetBuildDepends
exts :: [DynOption]
exts = [DynOption]
-> (Language -> [DynOption]) -> Maybe Language -> [DynOption]
forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] Language -> [DynOption]
langExt Maybe Language
defaultLanguage [DynOption] -> [DynOption] -> [DynOption]
forall a. [a] -> [a] -> [a]
++ (Extension -> DynOption) -> [Extension] -> [DynOption]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Extension -> DynOption
extToDynOption [Extension]
defaultExtensions
langExt :: Language -> [DynOption]
langExt =
DynOption -> [DynOption]
forall (f :: * -> *) a. Applicative f => a -> f a
pure (DynOption -> [DynOption])
-> (Language -> DynOption) -> Language -> [DynOption]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> DynOption
DynOption (String -> DynOption)
-> (Language -> String) -> Language -> DynOption
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String
"-X" String -> ShowS
forall a. Semigroup a => a -> a -> a
<>) ShowS -> (Language -> String) -> Language -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. \case
UnknownLanguage String
lan -> String
lan
Language
lan -> Language -> String
forall a. Show a => a -> String
show Language
lan
extToDynOption :: Extension -> DynOption
extToDynOption =
String -> DynOption
DynOption (String -> DynOption)
-> (Extension -> String) -> Extension -> DynOption
forall b c a. (b -> c) -> (a -> b) -> a -> c
. \case
EnableExtension KnownExtension
e -> String
"-X" String -> ShowS
forall a. [a] -> [a] -> [a]
++ KnownExtension -> String
forall a. Show a => a -> String
show KnownExtension
e
DisableExtension KnownExtension
e -> String
"-XNo" String -> ShowS
forall a. [a] -> [a] -> [a]
++ KnownExtension -> String
forall a. Show a => a -> String
show KnownExtension
e
UnknownExtension String
e -> String
"-X" String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
e
extractFromLibrary :: Library -> ([String], ([DynOption], [String]))
extractFromLibrary Library {Bool
[ModuleReexport]
[ModuleName]
BuildInfo
LibraryName
LibraryVisibility
libName :: Library -> LibraryName
exposedModules :: Library -> [ModuleName]
reexportedModules :: Library -> [ModuleReexport]
signatures :: Library -> [ModuleName]
libExposed :: Library -> Bool
libVisibility :: Library -> LibraryVisibility
libBuildInfo :: Library -> BuildInfo
libBuildInfo :: BuildInfo
libVisibility :: LibraryVisibility
libExposed :: Bool
signatures :: [ModuleName]
reexportedModules :: [ModuleReexport]
exposedModules :: [ModuleName]
libName :: LibraryName
..} =
[String] -> BuildInfo -> ([String], ([DynOption], [String]))
extractFromBuildInfo (ModuleName -> String
ModuleName.toFilePath (ModuleName -> String) -> [ModuleName] -> [String]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [ModuleName]
exposedModules) BuildInfo
libBuildInfo
extractFromExecutable :: Executable -> ([String], ([DynOption], [String]))
extractFromExecutable Executable {String
BuildInfo
ExecutableScope
UnqualComponentName
exeName :: Executable -> UnqualComponentName
modulePath :: Executable -> String
exeScope :: Executable -> ExecutableScope
buildInfo :: Executable -> BuildInfo
buildInfo :: BuildInfo
exeScope :: ExecutableScope
modulePath :: String
exeName :: UnqualComponentName
..} =
[String] -> BuildInfo -> ([String], ([DynOption], [String]))
extractFromBuildInfo [String
modulePath] BuildInfo
buildInfo
extractFromTestSuite :: TestSuite -> ([String], ([DynOption], [String]))
extractFromTestSuite TestSuite {BuildInfo
TestSuiteInterface
UnqualComponentName
testName :: TestSuite -> UnqualComponentName
testInterface :: TestSuite -> TestSuiteInterface
testBuildInfo :: TestSuite -> BuildInfo
testBuildInfo :: BuildInfo
testInterface :: TestSuiteInterface
testName :: UnqualComponentName
..} =
[String] -> BuildInfo -> ([String], ([DynOption], [String]))
extractFromBuildInfo [String]
mainPath BuildInfo
testBuildInfo
where
mainPath :: [String]
mainPath = case TestSuiteInterface
testInterface of
TestSuiteExeV10 Version
_ String
p -> [String
p]
TestSuiteLibV09 Version
_ ModuleName
p -> [ModuleName -> String
ModuleName.toFilePath ModuleName
p]
TestSuiteUnsupported {} -> []
extractFromBenchmark :: Benchmark -> ([String], ([DynOption], [String]))
extractFromBenchmark Benchmark {BuildInfo
BenchmarkInterface
UnqualComponentName
benchmarkName :: Benchmark -> UnqualComponentName
benchmarkInterface :: Benchmark -> BenchmarkInterface
benchmarkBuildInfo :: Benchmark -> BuildInfo
benchmarkBuildInfo :: BuildInfo
benchmarkInterface :: BenchmarkInterface
benchmarkName :: UnqualComponentName
..} =
[String] -> BuildInfo -> ([String], ([DynOption], [String]))
extractFromBuildInfo [String]
mainPath BuildInfo
benchmarkBuildInfo
where
mainPath :: [String]
mainPath = case BenchmarkInterface
benchmarkInterface of
BenchmarkExeV10 Version
_ String
p -> [String
p]
BenchmarkUnsupported {} -> []