cabal-install-3.6.0.0: src/Distribution/Client/ProjectBuilding/Types.hs
{-# LANGUAGE DeriveDataTypeable #-}
-- | 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.Types (DocsResult, TestsResult)
import Distribution.Client.FileMonitor (MonitorChangedReason(..))
import Distribution.Package (UnitId, PackageId)
import Distribution.InstalledPackageInfo (InstalledPackageInfo)
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, Typeable)
instance Exception BuildFailure
-- | Detail on the reason that a package failed to build.
--
data BuildFailureReason = DependentFailed PackageId
| DownloadFailed SomeException
| UnpackFailed SomeException
| ConfigureFailed SomeException
| BuildFailed SomeException
| ReplFailed SomeException
| HaddocksFailed SomeException
| TestsFailed SomeException
| BenchFailed SomeException
| InstallFailed SomeException
deriving Show