cabal-install-3.14.1.1: src/Distribution/Client/ProjectBuilding/Types.hs
-- | Types for the "Distribution.Client.ProjectBuilding"
--
-- Moved out to avoid module cycles.
module Distribution.Client.ProjectBuilding.Types
( -- * Pre-build status
BuildStatusMap
, BuildStatus (..)
, buildStatusRequiresBuild
, buildStatusToString
, BuildStatusRebuild (..)
, BuildReason (..)
, MonitorChangedReason (..)
-- * Build outcomes
, BuildOutcomes
, BuildOutcome
, BuildResult (..)
, BuildFailure (..)
, BuildFailureReason (..)
) where
import Distribution.Client.Compat.Prelude
import Prelude ()
import Distribution.Client.FileMonitor (MonitorChangedReason (..))
import Distribution.Client.Types (DocsResult, TestsResult)
import Distribution.InstalledPackageInfo (InstalledPackageInfo)
import Distribution.Package (PackageId, UnitId)
import Distribution.Simple.LocalBuildInfo (ComponentName)
------------------------------------------------------------------------------
-- Pre-build status: result of the dry run
--
-- | The 'BuildStatus' of every package in the 'ElaboratedInstallPlan'.
--
-- This is used as the result of the dry-run of building an install plan.
type BuildStatusMap = Map UnitId BuildStatus
-- | The build status for an individual package is the state that the
-- package is in /prior/ to initiating a (re)build.
--
-- This should not be confused with a 'BuildResult' which is the result
-- /after/ successfully building a package.
--
-- It serves two purposes:
--
-- * For dry-run output, it lets us explain to the user if and why a package
-- is going to be (re)built.
--
-- * It tell us what step to start or resume building from, and carries
-- enough information for us to be able to do so.
data BuildStatus
= -- | The package is in the 'InstallPlan.PreExisting' state, so does not
-- need building.
BuildStatusPreExisting
| -- | The package is in the 'InstallPlan.Installed' state, so does not
-- need building.
BuildStatusInstalled
| -- | The package has not been downloaded yet, so it will have to be
-- downloaded, unpacked and built.
BuildStatusDownload
| -- | The package has not been unpacked yet, so it will have to be
-- unpacked and built.
BuildStatusUnpack FilePath
| -- | The package exists in a local dir already, and just needs building
-- or rebuilding. So this can only happen for 'BuildInplaceOnly' style
-- packages.
BuildStatusRebuild FilePath BuildStatusRebuild
| -- | The package exists in a local dir already, and is fully up to date.
-- So this package can be put into the 'InstallPlan.Installed' state
-- and it does not need to be built.
BuildStatusUpToDate BuildResult
-- | Which 'BuildStatus' values indicate we'll have to do some build work of
-- some sort. In particular we use this as part of checking if any of a
-- package's deps have changed.
buildStatusRequiresBuild :: BuildStatus -> Bool
buildStatusRequiresBuild BuildStatusPreExisting = False
buildStatusRequiresBuild BuildStatusInstalled = False
buildStatusRequiresBuild BuildStatusUpToDate{} = False
buildStatusRequiresBuild _ = True
-- | This is primarily here for debugging. It's not actually used anywhere.
buildStatusToString :: BuildStatus -> String
buildStatusToString BuildStatusPreExisting = "BuildStatusPreExisting"
buildStatusToString BuildStatusInstalled = "BuildStatusInstalled"
buildStatusToString BuildStatusDownload = "BuildStatusDownload"
buildStatusToString (BuildStatusUnpack fp) = "BuildStatusUnpack " ++ show fp
buildStatusToString (BuildStatusRebuild fp _) = "BuildStatusRebuild " ++ show fp
buildStatusToString (BuildStatusUpToDate _) = "BuildStatusUpToDate"
-- | For a package that is going to be built or rebuilt, the state it's in now.
--
-- So again, this tells us why a package needs to be rebuilt and what build
-- phases need to be run. The 'MonitorChangedReason' gives us details like
-- which file changed, which is mainly for high verbosity debug output.
data BuildStatusRebuild
= -- | The package configuration changed, so the configure and build phases
-- needs to be (re)run.
BuildStatusConfigure (MonitorChangedReason ())
| -- | The configuration has not changed but the build phase needs to be
-- rerun. We record the reason the (re)build is needed.
--
-- The optional registration info here tells us if we've registered the
-- package already, or if we still need to do that after building.
-- @Just Nothing@ indicates that we know that no registration is
-- necessary (e.g., executable.)
BuildStatusBuild (Maybe (Maybe InstalledPackageInfo)) BuildReason
data BuildReason
= -- | The dependencies of this package have been (re)built so the build
-- phase needs to be rerun.
BuildReasonDepsRebuilt
| -- | Changes in files within the package (or first run or corrupt cache)
BuildReasonFilesChanged (MonitorChangedReason ())
| -- | An important special case is that no files have changed but the
-- set of components the /user asked to build/ has changed. We track the
-- set of components /we have built/, which of course only grows (until
-- some other change resets it).
--
-- The @Set 'ComponentName'@ is the set of components we have built
-- previously. When we update the monitor we take the union of the ones
-- we have built previously with the ones the user has asked for this
-- time and save those. See 'updatePackageBuildFileMonitor'.
BuildReasonExtraTargets (Set ComponentName)
| -- | Although we're not going to build any additional targets as a whole,
-- we're going to build some part of a component or run a repl or any
-- other action that does not result in additional persistent artifacts.
BuildReasonEphemeralTargets
------------------------------------------------------------------------------
-- Build outcomes: result of the build
--
-- | A summary of the outcome for building a whole set of packages.
type BuildOutcomes = Map UnitId BuildOutcome
-- | A summary of the outcome for building a single package: either success
-- or failure.
type BuildOutcome = Either BuildFailure BuildResult
-- | Information arising from successfully building a single package.
data BuildResult = BuildResult
{ buildResultDocs :: DocsResult
, buildResultTests :: TestsResult
, buildResultLogFile :: Maybe FilePath
}
deriving (Show)
-- | Information arising from the failure to build a single package.
data BuildFailure = BuildFailure
{ buildFailureLogFile :: Maybe FilePath
, buildFailureReason :: BuildFailureReason
}
deriving (Show)
instance Exception BuildFailure
-- | Detail on the reason that a package failed to build.
data BuildFailureReason
= DependentFailed PackageId
| GracefulFailure String
| DownloadFailed SomeException
| UnpackFailed SomeException
| ConfigureFailed SomeException
| BuildFailed SomeException
| ReplFailed SomeException
| HaddocksFailed SomeException
| TestsFailed SomeException
| BenchFailed SomeException
| InstallFailed SomeException
deriving (Show)