{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE RankNTypes #-}

module Distribution.Types.LocalBuildInfo (
    -- * The type

    LocalBuildInfo(..),

    -- * Convenience accessors

    localComponentId,
    localUnitId,
    localCompatPackageKey,
    localPackage,

    -- * Build targets of the 'LocalBuildInfo'.

    componentNameCLBIs,

    -- NB: the primes mean that they take a 'PackageDescription'
    -- which may not match 'localPkgDescr' in 'LocalBuildInfo'.
    -- More logical types would drop this argument, but
    -- at the moment, this is the ONLY supported function, because
    -- 'localPkgDescr' is not guaranteed to match.  At some point
    -- we will fix it and then we can use the (free) unprimed
    -- namespace for the correct commands.
    --
    -- See https://github.com/haskell/cabal/issues/3606 for more
    -- details.

    componentNameTargets',
    unitIdTarget',
    allTargetsInBuildOrder',
    withAllTargetsInBuildOrder',
    neededTargetsInBuildOrder',
    withNeededTargetsInBuildOrder',
    testCoverage,

    -- * Functions you SHOULD NOT USE (yet), but are defined here to
    -- prevent someone from accidentally defining them

    componentNameTargets,
    unitIdTarget,
    allTargetsInBuildOrder,
    withAllTargetsInBuildOrder,
    neededTargetsInBuildOrder,
    withNeededTargetsInBuildOrder,
  ) where

import Prelude ()
import Distribution.Compat.Prelude

import Distribution.Types.PackageDescription
import Distribution.Types.ComponentLocalBuildInfo
import Distribution.Types.ComponentRequestedSpec
import Distribution.Types.ComponentId
import Distribution.Types.PackageId
import Distribution.Types.UnitId
import Distribution.Types.TargetInfo

import Distribution.Simple.InstallDirs hiding (absoluteInstallDirs,
                                               prefixRelativeInstallDirs,
                                               substPathTemplate, )
import Distribution.Simple.Program
import Distribution.PackageDescription
import Distribution.Simple.Compiler
import Distribution.Simple.PackageIndex
import Distribution.Simple.Setup
import Distribution.System
import Distribution.Pretty

import Distribution.Compat.Graph (Graph)
import qualified Distribution.Compat.Graph as Graph
import qualified Data.Map as Map

-- | Data cached after configuration step.  See also
-- 'Distribution.Simple.Setup.ConfigFlags'.
data LocalBuildInfo = LocalBuildInfo {
        LocalBuildInfo -> ConfigFlags
configFlags   :: ConfigFlags,
        -- ^ Options passed to the configuration step.
        -- Needed to re-run configuration when .cabal is out of date
        LocalBuildInfo -> FlagAssignment
flagAssignment :: FlagAssignment,
        -- ^ The final set of flags which were picked for this package
        LocalBuildInfo -> ComponentRequestedSpec
componentEnabledSpec :: ComponentRequestedSpec,
        -- ^ What components were enabled during configuration, and why.
        LocalBuildInfo -> [String]
extraConfigArgs     :: [String],
        -- ^ Extra args on the command line for the configuration step.
        -- Needed to re-run configuration when .cabal is out of date
        LocalBuildInfo -> InstallDirTemplates
installDirTemplates :: InstallDirTemplates,
                -- ^ The installation directories for the various different
                -- kinds of files
        --TODO: inplaceDirTemplates :: InstallDirs FilePath
        LocalBuildInfo -> Compiler
compiler      :: Compiler,
                -- ^ The compiler we're building with
        LocalBuildInfo -> Platform
hostPlatform  :: Platform,
                -- ^ The platform we're building for
        LocalBuildInfo -> String
buildDir      :: FilePath,
                -- ^ Where to build the package.
        LocalBuildInfo -> Maybe String
cabalFilePath :: Maybe FilePath,
                -- ^ Path to the cabal file, if given during configuration.
        LocalBuildInfo -> Graph ComponentLocalBuildInfo
componentGraph :: Graph ComponentLocalBuildInfo,
                -- ^ All the components to build, ordered by topological
                -- sort, and with their INTERNAL dependencies over the
                -- intrapackage dependency graph.
                -- TODO: this is assumed to be short; otherwise we want
                -- some sort of ordered map.
        LocalBuildInfo -> Map ComponentName [ComponentLocalBuildInfo]
componentNameMap :: Map ComponentName [ComponentLocalBuildInfo],
                -- ^ A map from component name to all matching
                -- components.  These coincide with 'componentGraph'
        LocalBuildInfo -> InstalledPackageIndex
installedPkgs :: InstalledPackageIndex,
                -- ^ All the info about the installed packages that the
                -- current package depends on (directly or indirectly).
                -- The copy saved on disk does NOT include internal
                -- dependencies (because we just don't have enough
                -- information at this point to have an
                -- 'InstalledPackageInfo' for an internal dep), but we
                -- will often update it with the internal dependencies;
                -- see for example 'Distribution.Simple.Build.build'.
                -- (This admonition doesn't apply for per-component builds.)
        LocalBuildInfo -> Maybe String
pkgDescrFile  :: Maybe FilePath,
                -- ^ the filename containing the .cabal file, if available
        LocalBuildInfo -> PackageDescription
localPkgDescr :: PackageDescription,
                -- ^ WARNING WARNING WARNING Be VERY careful about using
                -- this function; we haven't deprecated it but using it
                -- could introduce subtle bugs related to
                -- 'HookedBuildInfo'.
                --
                -- In principle, this is supposed to contain the
                -- resolved package description, that does not contain
                -- any conditionals.  However, it MAY NOT contain
                -- the description with a 'HookedBuildInfo' applied
                -- to it; see 'HookedBuildInfo' for the whole sordid saga.
                -- As much as possible, Cabal library should avoid using
                -- this parameter.
        LocalBuildInfo -> ProgramDb
withPrograms  :: ProgramDb, -- ^Location and args for all programs
        LocalBuildInfo -> PackageDBStack
withPackageDB :: PackageDBStack,  -- ^What package database to use, global\/user
        LocalBuildInfo -> Bool
withVanillaLib:: Bool,  -- ^Whether to build normal libs.
        LocalBuildInfo -> Bool
withProfLib   :: Bool,  -- ^Whether to build profiling versions of libs.
        LocalBuildInfo -> Bool
withSharedLib :: Bool,  -- ^Whether to build shared versions of libs.
        LocalBuildInfo -> Bool
withStaticLib :: Bool,  -- ^Whether to build static versions of libs (with all other libs rolled in)
        LocalBuildInfo -> Bool
withDynExe    :: Bool,  -- ^Whether to link executables dynamically
        LocalBuildInfo -> Bool
withFullyStaticExe :: Bool,  -- ^Whether to link executables fully statically
        LocalBuildInfo -> Bool
withProfExe   :: Bool,  -- ^Whether to build executables for profiling.
        LocalBuildInfo -> ProfDetailLevel
withProfLibDetail :: ProfDetailLevel, -- ^Level of automatic profile detail.
        LocalBuildInfo -> ProfDetailLevel
withProfExeDetail :: ProfDetailLevel, -- ^Level of automatic profile detail.
        LocalBuildInfo -> OptimisationLevel
withOptimization :: OptimisationLevel, -- ^Whether to build with optimization (if available).
        LocalBuildInfo -> DebugInfoLevel
withDebugInfo :: DebugInfoLevel, -- ^Whether to emit debug info (if available).
        LocalBuildInfo -> Bool
withGHCiLib   :: Bool,  -- ^Whether to build libs suitable for use with GHCi.
        LocalBuildInfo -> Bool
splitSections :: Bool,  -- ^Use -split-sections with GHC, if available
        LocalBuildInfo -> Bool
splitObjs     :: Bool,  -- ^Use -split-objs with GHC, if available
        LocalBuildInfo -> Bool
stripExes     :: Bool,  -- ^Whether to strip executables during install
        LocalBuildInfo -> Bool
stripLibs     :: Bool,  -- ^Whether to strip libraries during install
        LocalBuildInfo -> Bool
exeCoverage :: Bool,  -- ^Whether to enable executable program coverage
        LocalBuildInfo -> Bool
libCoverage :: Bool,  -- ^Whether to enable library program coverage
        LocalBuildInfo -> PathTemplate
progPrefix    :: PathTemplate, -- ^Prefix to be prepended to installed executables
        LocalBuildInfo -> PathTemplate
progSuffix    :: PathTemplate, -- ^Suffix to be appended to installed executables
        LocalBuildInfo -> Bool
relocatable   :: Bool --  ^Whether to build a relocatable package
  } deriving ((forall x. LocalBuildInfo -> Rep LocalBuildInfo x)
-> (forall x. Rep LocalBuildInfo x -> LocalBuildInfo)
-> Generic LocalBuildInfo
forall x. Rep LocalBuildInfo x -> LocalBuildInfo
forall x. LocalBuildInfo -> Rep LocalBuildInfo x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. LocalBuildInfo -> Rep LocalBuildInfo x
$cto :: forall x. Rep LocalBuildInfo x -> LocalBuildInfo
Generic, ReadPrec [LocalBuildInfo]
ReadPrec LocalBuildInfo
Int -> ReadS LocalBuildInfo
ReadS [LocalBuildInfo]
(Int -> ReadS LocalBuildInfo)
-> ReadS [LocalBuildInfo]
-> ReadPrec LocalBuildInfo
-> ReadPrec [LocalBuildInfo]
-> Read LocalBuildInfo
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: Int -> ReadS LocalBuildInfo
readsPrec :: Int -> ReadS LocalBuildInfo
$creadList :: ReadS [LocalBuildInfo]
readList :: ReadS [LocalBuildInfo]
$creadPrec :: ReadPrec LocalBuildInfo
readPrec :: ReadPrec LocalBuildInfo
$creadListPrec :: ReadPrec [LocalBuildInfo]
readListPrec :: ReadPrec [LocalBuildInfo]
Read, Int -> LocalBuildInfo -> ShowS
[LocalBuildInfo] -> ShowS
LocalBuildInfo -> String
(Int -> LocalBuildInfo -> ShowS)
-> (LocalBuildInfo -> String)
-> ([LocalBuildInfo] -> ShowS)
-> Show LocalBuildInfo
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> LocalBuildInfo -> ShowS
showsPrec :: Int -> LocalBuildInfo -> ShowS
$cshow :: LocalBuildInfo -> String
show :: LocalBuildInfo -> String
$cshowList :: [LocalBuildInfo] -> ShowS
showList :: [LocalBuildInfo] -> ShowS
Show, Typeable)

instance Binary LocalBuildInfo
instance Structured LocalBuildInfo

-------------------------------------------------------------------------------
-- Accessor functions

-- TODO: Get rid of these functions, as much as possible.  They are
-- a bit useful in some cases, but you should be very careful!

-- | Extract the 'ComponentId' from the public library component of a
-- 'LocalBuildInfo' if it exists, or make a fake component ID based
-- on the package ID.
localComponentId :: LocalBuildInfo -> ComponentId
localComponentId :: LocalBuildInfo -> ComponentId
localComponentId LocalBuildInfo
lbi =
    case LocalBuildInfo -> ComponentName -> [ComponentLocalBuildInfo]
componentNameCLBIs LocalBuildInfo
lbi (LibraryName -> ComponentName
CLibName LibraryName
LMainLibName) of
        [LibComponentLocalBuildInfo { componentComponentId :: ComponentLocalBuildInfo -> ComponentId
componentComponentId = ComponentId
cid }]
          -> ComponentId
cid
        [ComponentLocalBuildInfo]
_ -> String -> ComponentId
mkComponentId (PackageId -> String
forall a. Pretty a => a -> String
prettyShow (LocalBuildInfo -> PackageId
localPackage LocalBuildInfo
lbi))

-- | Extract the 'PackageIdentifier' of a 'LocalBuildInfo'.
-- This is a "safe" use of 'localPkgDescr'
localPackage :: LocalBuildInfo -> PackageId
localPackage :: LocalBuildInfo -> PackageId
localPackage LocalBuildInfo
lbi = PackageDescription -> PackageId
package (LocalBuildInfo -> PackageDescription
localPkgDescr LocalBuildInfo
lbi)

-- | Extract the 'UnitId' from the library component of a
-- 'LocalBuildInfo' if it exists, or make a fake unit ID based on
-- the package ID.
localUnitId :: LocalBuildInfo -> UnitId
localUnitId :: LocalBuildInfo -> UnitId
localUnitId LocalBuildInfo
lbi =
    case LocalBuildInfo -> ComponentName -> [ComponentLocalBuildInfo]
componentNameCLBIs LocalBuildInfo
lbi (LibraryName -> ComponentName
CLibName LibraryName
LMainLibName) of
        [LibComponentLocalBuildInfo { componentUnitId :: ComponentLocalBuildInfo -> UnitId
componentUnitId = UnitId
uid }]
          -> UnitId
uid
        [ComponentLocalBuildInfo]
_ -> PackageId -> UnitId
mkLegacyUnitId (PackageId -> UnitId) -> PackageId -> UnitId
forall a b. (a -> b) -> a -> b
$ LocalBuildInfo -> PackageId
localPackage LocalBuildInfo
lbi

-- | Extract the compatibility package key from the public library component of a
-- 'LocalBuildInfo' if it exists, or make a fake package key based
-- on the package ID.
localCompatPackageKey :: LocalBuildInfo -> String
localCompatPackageKey :: LocalBuildInfo -> String
localCompatPackageKey LocalBuildInfo
lbi =
    case LocalBuildInfo -> ComponentName -> [ComponentLocalBuildInfo]
componentNameCLBIs LocalBuildInfo
lbi (LibraryName -> ComponentName
CLibName LibraryName
LMainLibName) of
        [LibComponentLocalBuildInfo { componentCompatPackageKey :: ComponentLocalBuildInfo -> String
componentCompatPackageKey = String
pk }]
          -> String
pk
        [ComponentLocalBuildInfo]
_ -> PackageId -> String
forall a. Pretty a => a -> String
prettyShow (LocalBuildInfo -> PackageId
localPackage LocalBuildInfo
lbi)

-- | Convenience function to generate a default 'TargetInfo' from a
-- 'ComponentLocalBuildInfo'.  The idea is to call this once, and then
-- use 'TargetInfo' everywhere else.  Private to this module.
mkTargetInfo :: PackageDescription -> LocalBuildInfo -> ComponentLocalBuildInfo -> TargetInfo
mkTargetInfo :: PackageDescription
-> LocalBuildInfo -> ComponentLocalBuildInfo -> TargetInfo
mkTargetInfo PackageDescription
pkg_descr LocalBuildInfo
_lbi ComponentLocalBuildInfo
clbi =
    TargetInfo {
        targetCLBI :: ComponentLocalBuildInfo
targetCLBI = ComponentLocalBuildInfo
clbi,
        -- NB: @pkg_descr@, not @localPkgDescr lbi@!
        targetComponent :: Component
targetComponent = PackageDescription -> ComponentName -> Component
getComponent PackageDescription
pkg_descr
                                       (ComponentLocalBuildInfo -> ComponentName
componentLocalName ComponentLocalBuildInfo
clbi)
     }

-- | Return all 'TargetInfo's associated with 'ComponentName'.
-- In the presence of Backpack there may be more than one!
-- Has a prime because it takes a 'PackageDescription' argument
-- which may disagree with 'localPkgDescr' in 'LocalBuildInfo'.
componentNameTargets' :: PackageDescription -> LocalBuildInfo -> ComponentName -> [TargetInfo]
componentNameTargets' :: PackageDescription
-> LocalBuildInfo -> ComponentName -> [TargetInfo]
componentNameTargets' PackageDescription
pkg_descr LocalBuildInfo
lbi ComponentName
cname =
    case ComponentName
-> Map ComponentName [ComponentLocalBuildInfo]
-> Maybe [ComponentLocalBuildInfo]
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup ComponentName
cname (LocalBuildInfo -> Map ComponentName [ComponentLocalBuildInfo]
componentNameMap LocalBuildInfo
lbi) of
        Just [ComponentLocalBuildInfo]
clbis -> (ComponentLocalBuildInfo -> TargetInfo)
-> [ComponentLocalBuildInfo] -> [TargetInfo]
forall a b. (a -> b) -> [a] -> [b]
map (PackageDescription
-> LocalBuildInfo -> ComponentLocalBuildInfo -> TargetInfo
mkTargetInfo PackageDescription
pkg_descr LocalBuildInfo
lbi) [ComponentLocalBuildInfo]
clbis
        Maybe [ComponentLocalBuildInfo]
Nothing -> []

unitIdTarget' :: PackageDescription -> LocalBuildInfo -> UnitId -> Maybe TargetInfo
unitIdTarget' :: PackageDescription -> LocalBuildInfo -> UnitId -> Maybe TargetInfo
unitIdTarget' PackageDescription
pkg_descr LocalBuildInfo
lbi UnitId
uid =
    case Key ComponentLocalBuildInfo
-> Graph ComponentLocalBuildInfo -> Maybe ComponentLocalBuildInfo
forall a. IsNode a => Key a -> Graph a -> Maybe a
Graph.lookup Key ComponentLocalBuildInfo
UnitId
uid (LocalBuildInfo -> Graph ComponentLocalBuildInfo
componentGraph LocalBuildInfo
lbi) of
        Just ComponentLocalBuildInfo
clbi -> TargetInfo -> Maybe TargetInfo
forall a. a -> Maybe a
Just (PackageDescription
-> LocalBuildInfo -> ComponentLocalBuildInfo -> TargetInfo
mkTargetInfo PackageDescription
pkg_descr LocalBuildInfo
lbi ComponentLocalBuildInfo
clbi)
        Maybe ComponentLocalBuildInfo
Nothing -> Maybe TargetInfo
forall a. Maybe a
Nothing

-- | Return all 'ComponentLocalBuildInfo's associated with 'ComponentName'.
-- In the presence of Backpack there may be more than one!
componentNameCLBIs :: LocalBuildInfo -> ComponentName -> [ComponentLocalBuildInfo]
componentNameCLBIs :: LocalBuildInfo -> ComponentName -> [ComponentLocalBuildInfo]
componentNameCLBIs LocalBuildInfo
lbi ComponentName
cname =
    case ComponentName
-> Map ComponentName [ComponentLocalBuildInfo]
-> Maybe [ComponentLocalBuildInfo]
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup ComponentName
cname (LocalBuildInfo -> Map ComponentName [ComponentLocalBuildInfo]
componentNameMap LocalBuildInfo
lbi) of
        Just [ComponentLocalBuildInfo]
clbis -> [ComponentLocalBuildInfo]
clbis
        Maybe [ComponentLocalBuildInfo]
Nothing -> []

-- TODO: Maybe cache topsort (Graph can do this)

-- | Return the list of default 'TargetInfo's associated with a
-- configured package, in the order they need to be built.
-- Has a prime because it takes a 'PackageDescription' argument
-- which may disagree with 'localPkgDescr' in 'LocalBuildInfo'.
allTargetsInBuildOrder' :: PackageDescription -> LocalBuildInfo -> [TargetInfo]
allTargetsInBuildOrder' :: PackageDescription -> LocalBuildInfo -> [TargetInfo]
allTargetsInBuildOrder' PackageDescription
pkg_descr LocalBuildInfo
lbi
    = (ComponentLocalBuildInfo -> TargetInfo)
-> [ComponentLocalBuildInfo] -> [TargetInfo]
forall a b. (a -> b) -> [a] -> [b]
map (PackageDescription
-> LocalBuildInfo -> ComponentLocalBuildInfo -> TargetInfo
mkTargetInfo PackageDescription
pkg_descr LocalBuildInfo
lbi) (Graph ComponentLocalBuildInfo -> [ComponentLocalBuildInfo]
forall a. Graph a -> [a]
Graph.revTopSort (LocalBuildInfo -> Graph ComponentLocalBuildInfo
componentGraph LocalBuildInfo
lbi))

-- | Execute @f@ for every 'TargetInfo' in the package, respecting the
-- build dependency order.  (TODO: We should use Shake!)
-- Has a prime because it takes a 'PackageDescription' argument
-- which may disagree with 'localPkgDescr' in 'LocalBuildInfo'.
withAllTargetsInBuildOrder' :: PackageDescription -> LocalBuildInfo -> (TargetInfo -> IO ()) -> IO ()
withAllTargetsInBuildOrder' :: PackageDescription
-> LocalBuildInfo -> (TargetInfo -> IO ()) -> IO ()
withAllTargetsInBuildOrder' PackageDescription
pkg_descr LocalBuildInfo
lbi TargetInfo -> IO ()
f
    = [IO ()] -> IO ()
forall (t :: * -> *) (m :: * -> *) a.
(Foldable t, Monad m) =>
t (m a) -> m ()
sequence_ [ TargetInfo -> IO ()
f TargetInfo
target | TargetInfo
target <- PackageDescription -> LocalBuildInfo -> [TargetInfo]
allTargetsInBuildOrder' PackageDescription
pkg_descr LocalBuildInfo
lbi ]

-- | Return the list of all targets needed to build the @uids@, in
-- the order they need to be built.
-- Has a prime because it takes a 'PackageDescription' argument
-- which may disagree with 'localPkgDescr' in 'LocalBuildInfo'.
neededTargetsInBuildOrder' :: PackageDescription -> LocalBuildInfo -> [UnitId] -> [TargetInfo]
neededTargetsInBuildOrder' :: PackageDescription -> LocalBuildInfo -> [UnitId] -> [TargetInfo]
neededTargetsInBuildOrder' PackageDescription
pkg_descr LocalBuildInfo
lbi [UnitId]
uids =
  case Graph ComponentLocalBuildInfo
-> [Key ComponentLocalBuildInfo] -> Maybe [ComponentLocalBuildInfo]
forall a. Graph a -> [Key a] -> Maybe [a]
Graph.closure (LocalBuildInfo -> Graph ComponentLocalBuildInfo
componentGraph LocalBuildInfo
lbi) [Key ComponentLocalBuildInfo]
[UnitId]
uids of
    Maybe [ComponentLocalBuildInfo]
Nothing -> String -> [TargetInfo]
forall a. HasCallStack => String -> a
error (String -> [TargetInfo]) -> String -> [TargetInfo]
forall a b. (a -> b) -> a -> b
$ String
"localBuildPlan: missing uids " String -> ShowS
forall a. [a] -> [a] -> [a]
++ String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
", " ((UnitId -> String) -> [UnitId] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map UnitId -> String
forall a. Pretty a => a -> String
prettyShow [UnitId]
uids)
    Just [ComponentLocalBuildInfo]
clos -> (ComponentLocalBuildInfo -> TargetInfo)
-> [ComponentLocalBuildInfo] -> [TargetInfo]
forall a b. (a -> b) -> [a] -> [b]
map (PackageDescription
-> LocalBuildInfo -> ComponentLocalBuildInfo -> TargetInfo
mkTargetInfo PackageDescription
pkg_descr LocalBuildInfo
lbi) (Graph ComponentLocalBuildInfo -> [ComponentLocalBuildInfo]
forall a. Graph a -> [a]
Graph.revTopSort ([ComponentLocalBuildInfo] -> Graph ComponentLocalBuildInfo
forall a. (IsNode a, Show (Key a)) => [a] -> Graph a
Graph.fromDistinctList [ComponentLocalBuildInfo]
clos))

-- | Execute @f@ for every 'TargetInfo' needed to build @uid@s, respecting
-- the build dependency order.
-- Has a prime because it takes a 'PackageDescription' argument
-- which may disagree with 'localPkgDescr' in 'LocalBuildInfo'.
withNeededTargetsInBuildOrder' :: PackageDescription -> LocalBuildInfo -> [UnitId] -> (TargetInfo -> IO ()) -> IO ()
withNeededTargetsInBuildOrder' :: PackageDescription
-> LocalBuildInfo -> [UnitId] -> (TargetInfo -> IO ()) -> IO ()
withNeededTargetsInBuildOrder' PackageDescription
pkg_descr LocalBuildInfo
lbi [UnitId]
uids TargetInfo -> IO ()
f
    = [IO ()] -> IO ()
forall (t :: * -> *) (m :: * -> *) a.
(Foldable t, Monad m) =>
t (m a) -> m ()
sequence_ [ TargetInfo -> IO ()
f TargetInfo
target | TargetInfo
target <- PackageDescription -> LocalBuildInfo -> [UnitId] -> [TargetInfo]
neededTargetsInBuildOrder' PackageDescription
pkg_descr LocalBuildInfo
lbi [UnitId]
uids ]

-- | Is coverage enabled for test suites? In practice, this requires library
-- and executable profiling to be enabled.
testCoverage :: LocalBuildInfo -> Bool
testCoverage :: LocalBuildInfo -> Bool
testCoverage LocalBuildInfo
lbi = LocalBuildInfo -> Bool
exeCoverage LocalBuildInfo
lbi Bool -> Bool -> Bool
&& LocalBuildInfo -> Bool
libCoverage LocalBuildInfo
lbi

-------------------------------------------------------------------------------
-- Stub functions to prevent someone from accidentally defining them

{-# WARNING componentNameTargets, unitIdTarget, allTargetsInBuildOrder, withAllTargetsInBuildOrder, neededTargetsInBuildOrder, withNeededTargetsInBuildOrder "By using this function, you may be introducing a bug where you retrieve a 'Component' which does not have 'HookedBuildInfo' applied to it.  See the documentation for 'HookedBuildInfo' for an explanation of the issue.  If you have a 'PakcageDescription' handy (NOT from the 'LocalBuildInfo'), try using the primed version of the function, which takes it as an extra argument." #-}

componentNameTargets :: LocalBuildInfo -> ComponentName -> [TargetInfo]
componentNameTargets :: LocalBuildInfo -> ComponentName -> [TargetInfo]
componentNameTargets LocalBuildInfo
lbi = PackageDescription
-> LocalBuildInfo -> ComponentName -> [TargetInfo]
componentNameTargets' (LocalBuildInfo -> PackageDescription
localPkgDescr LocalBuildInfo
lbi) LocalBuildInfo
lbi

unitIdTarget :: LocalBuildInfo -> UnitId -> Maybe TargetInfo
unitIdTarget :: LocalBuildInfo -> UnitId -> Maybe TargetInfo
unitIdTarget LocalBuildInfo
lbi = PackageDescription -> LocalBuildInfo -> UnitId -> Maybe TargetInfo
unitIdTarget' (LocalBuildInfo -> PackageDescription
localPkgDescr LocalBuildInfo
lbi) LocalBuildInfo
lbi

allTargetsInBuildOrder :: LocalBuildInfo -> [TargetInfo]
allTargetsInBuildOrder :: LocalBuildInfo -> [TargetInfo]
allTargetsInBuildOrder LocalBuildInfo
lbi = PackageDescription -> LocalBuildInfo -> [TargetInfo]
allTargetsInBuildOrder' (LocalBuildInfo -> PackageDescription
localPkgDescr LocalBuildInfo
lbi) LocalBuildInfo
lbi

withAllTargetsInBuildOrder :: LocalBuildInfo -> (TargetInfo -> IO ()) -> IO ()
withAllTargetsInBuildOrder :: LocalBuildInfo -> (TargetInfo -> IO ()) -> IO ()
withAllTargetsInBuildOrder LocalBuildInfo
lbi = PackageDescription
-> LocalBuildInfo -> (TargetInfo -> IO ()) -> IO ()
withAllTargetsInBuildOrder' (LocalBuildInfo -> PackageDescription
localPkgDescr LocalBuildInfo
lbi) LocalBuildInfo
lbi

neededTargetsInBuildOrder :: LocalBuildInfo -> [UnitId] -> [TargetInfo]
neededTargetsInBuildOrder :: LocalBuildInfo -> [UnitId] -> [TargetInfo]
neededTargetsInBuildOrder LocalBuildInfo
lbi = PackageDescription -> LocalBuildInfo -> [UnitId] -> [TargetInfo]
neededTargetsInBuildOrder' (LocalBuildInfo -> PackageDescription
localPkgDescr LocalBuildInfo
lbi) LocalBuildInfo
lbi

withNeededTargetsInBuildOrder :: LocalBuildInfo -> [UnitId] -> (TargetInfo -> IO ()) -> IO ()
withNeededTargetsInBuildOrder :: LocalBuildInfo -> [UnitId] -> (TargetInfo -> IO ()) -> IO ()
withNeededTargetsInBuildOrder LocalBuildInfo
lbi = PackageDescription
-> LocalBuildInfo -> [UnitId] -> (TargetInfo -> IO ()) -> IO ()
withNeededTargetsInBuildOrder' (LocalBuildInfo -> PackageDescription
localPkgDescr LocalBuildInfo
lbi) LocalBuildInfo
lbi