stack-2.15.1: src/Stack/Types/Build/ConstructPlan.hs
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE OverloadedRecordDot #-}
-- | A module providing types and related helper functions used in module
-- "Stack.Build.ConstructPlan".
module Stack.Types.Build.ConstructPlan
( PackageInfo (..)
, CombinedMap
, M
, W (..)
, AddDepRes (..)
, toTask
, adrVersion
, adrHasLibrary
, Ctx (..)
, UnregisterState (..)
, ToolWarning (..)
) where
import Generics.Deriving.Monoid ( mappenddefault, memptydefault )
import RIO.Process ( HasProcessContext (..) )
import RIO.State ( StateT )
import RIO.Writer ( WriterT (..) )
import Stack.Package ( hasBuildableMainLibrary )
import Stack.Prelude hiding ( loadPackage )
import Stack.Types.Build
( Task (..), TaskType (..), taskProvides )
import Stack.Types.Build.Exception ( ConstructPlanException )
import Stack.Types.BuildConfig
( BuildConfig (..), HasBuildConfig(..) )
import Stack.Types.CompilerPaths ( HasCompiler (..) )
import Stack.Types.Config ( HasConfig (..) )
import Stack.Types.ConfigureOpts ( BaseConfigOpts )
import Stack.Types.Curator ( Curator )
import Stack.Types.DumpPackage ( DumpPackage )
import Stack.Types.EnvConfig
( EnvConfig (..), HasEnvConfig (..), HasSourceMap (..) )
import Stack.Types.GhcPkgId ( GhcPkgId )
import Stack.Types.GHCVariant ( HasGHCVariant (..) )
import Stack.Types.Installed
( InstallLocation, Installed (..), installedVersion )
import Stack.Types.Package
( ExeName (..), LocalPackage (..), Package (..)
, PackageSource (..)
)
import Stack.Types.ParentMap ( ParentMap )
import Stack.Types.Platform ( HasPlatform (..) )
import Stack.Types.Runner ( HasRunner (..) )
-- | Type representing information about packages, namely information about
-- whether or not a package is already installed and, unless the package is not
-- to be built (global packages), where its source code is located.
data PackageInfo
= PIOnlyInstalled InstallLocation Installed
-- ^ This indicates that the package is already installed, and that we
-- shouldn't build it from source. This is only the case for global
-- packages.
| PIOnlySource PackageSource
-- ^ This indicates that the package isn't installed, and we know where to
-- find its source.
| PIBoth PackageSource Installed
-- ^ This indicates that the package is installed and we know where to find
-- its source. We may want to reinstall from source.
deriving Show
-- | A type synonym representing dictionaries of package names, and combined
-- information about the package in respect of whether or not it is already
-- installed and, unless the package is not to be built (global packages), where
-- its source code is located.
type CombinedMap = Map PackageName PackageInfo
-- | Type synonym representing values used during the construction of a build
-- plan. The type is an instance of 'Monad', hence its name.
type M =
WriterT
W
-- ^ The output to be collected
( StateT
(Map PackageName (Either ConstructPlanException AddDepRes))
-- ^ Library map
(RIO Ctx)
)
-- | Type representing values used as the output to be collected during the
-- construction of a build plan.
data W = W
{ wFinals :: !(Map PackageName (Either ConstructPlanException Task))
-- ^ A dictionary of package names, and either a final task to perform when
-- building the package or an exception.
, wInstall :: !(Map Text InstallLocation)
-- ^ A dictionary of executables to be installed, and location where the
-- executable's binary is placed.
, wDirty :: !(Map PackageName Text)
-- ^ A dictionary of local packages, and the reason why the local package is
-- considered dirty.
, wWarnings :: !([StyleDoc] -> [StyleDoc])
-- ^ Warnings.
, wParents :: !ParentMap
-- ^ A dictionary of package names, and a list of pairs of the identifier
-- of a package depending on the package and the version range specified for
-- the dependency by that package. Used in the reporting of failure to
-- construct a build plan.
}
deriving Generic
instance Semigroup W where
(<>) = mappenddefault
instance Monoid W where
mempty = memptydefault
mappend = (<>)
-- | Type representing results of 'addDep'.
data AddDepRes
= ADRToInstall Task
-- ^ A task must be performed to provide the package name.
| ADRFound InstallLocation Installed
-- ^ An existing installation provides the package name.
deriving Show
toTask :: AddDepRes -> Maybe Task
toTask (ADRToInstall task) = Just task
toTask (ADRFound _ _) = Nothing
adrVersion :: AddDepRes -> Version
adrVersion (ADRToInstall task) = pkgVersion $ taskProvides task
adrVersion (ADRFound _ installed) = installedVersion installed
adrHasLibrary :: AddDepRes -> Bool
adrHasLibrary (ADRToInstall task) = case task.taskType of
TTLocalMutable lp -> packageHasLibrary lp.package
TTRemotePackage _ p _ -> packageHasLibrary p
where
-- make sure we consider sub-libraries as libraries too
packageHasLibrary :: Package -> Bool
packageHasLibrary p =
hasBuildableMainLibrary p || not (null p.subLibraries)
adrHasLibrary (ADRFound _ Library{}) = True
adrHasLibrary (ADRFound _ Executable{}) = False
-- | Type representing values used as the environment to be read from during the
-- construction of a build plan (the \'context\').
data Ctx = Ctx
{ baseConfigOpts :: !BaseConfigOpts
-- ^ Basic information used to determine configure options
, loadPackage :: !( PackageLocationImmutable
-> Map FlagName Bool
-> [Text]
-- ^ GHC options.
-> [Text]
-- ^ Cabal configure options.
-> M Package
)
, combinedMap :: !CombinedMap
-- ^ A dictionary of package names, and combined information about the
-- package in respect of whether or not it is already installed and, unless
-- the package is not to be built (global packages), where its source code
-- is located.
, ctxEnvConfig :: !EnvConfig
-- ^ Configuration after the environment has been setup.
, callStack :: ![PackageName]
, wanted :: !(Set PackageName)
, localNames :: !(Set PackageName)
, curator :: !(Maybe Curator)
, pathEnvVar :: !Text
}
instance HasPlatform Ctx where
platformL = configL . platformL
{-# INLINE platformL #-}
platformVariantL = configL . platformVariantL
{-# INLINE platformVariantL #-}
instance HasGHCVariant Ctx where
ghcVariantL = configL . ghcVariantL
{-# INLINE ghcVariantL #-}
instance HasLogFunc Ctx where
logFuncL = configL . logFuncL
instance HasRunner Ctx where
runnerL = configL . runnerL
instance HasStylesUpdate Ctx where
stylesUpdateL = runnerL . stylesUpdateL
instance HasTerm Ctx where
useColorL = runnerL . useColorL
termWidthL = runnerL . termWidthL
instance HasConfig Ctx where
configL = buildConfigL . lens (.config) (\x y -> x { config = y })
{-# INLINE configL #-}
instance HasPantryConfig Ctx where
pantryConfigL = configL . pantryConfigL
instance HasProcessContext Ctx where
processContextL = configL . processContextL
instance HasBuildConfig Ctx where
buildConfigL = envConfigL . lens
(.buildConfig)
(\x y -> x { buildConfig = y })
instance HasSourceMap Ctx where
sourceMapL = envConfigL . sourceMapL
instance HasCompiler Ctx where
compilerPathsL = envConfigL . compilerPathsL
instance HasEnvConfig Ctx where
envConfigL = lens (.ctxEnvConfig) (\x y -> x { ctxEnvConfig = y })
-- | State to be maintained during the calculation of local packages to
-- unregister.
data UnregisterState = UnregisterState
{ toUnregister :: !(Map GhcPkgId (PackageIdentifier, Text))
, toKeep :: ![DumpPackage]
, anyAdded :: !Bool
}
-- | Warn about tools in the snapshot definition. States the tool name
-- expected and the package name using it.
data ToolWarning
= ToolWarning ExeName PackageName
deriving Show