Types.hs 7.35 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
{-# 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

25 26 27
import Distribution.Client.Compat.Prelude
import Prelude ()

28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
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,
178
       buildResultLogFile :: Maybe FilePath
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201
     }
  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
202
                        | BenchFailed     SomeException
203 204
                        | InstallFailed   SomeException
  deriving Show