{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Distribution.Client.ProjectPlanOutput
(
writePlanExternalRepresentation
, PostBuildProjectStatus (..)
, updatePostBuildProjectStatus
, createPackageEnvironment
, writePlanGhcEnvironment
, argsEquivalentOfGhcEnvironmentFile
) where
import Distribution.Client.DistDirLayout
import Distribution.Client.HashValue (hashValue, showHashValue)
import Distribution.Client.ProjectBuilding.Types
import Distribution.Client.ProjectPlanning.Types
import Distribution.Client.Types.ConfiguredId (confInstId)
import Distribution.Client.Types.PackageLocation (PackageLocation (..))
import Distribution.Client.Types.Repo (RemoteRepo (..), Repo (..))
import Distribution.Client.Types.SourceRepo (SourceRepoMaybe, SourceRepositoryPackage (..))
import Distribution.Client.Version (cabalInstallVersion)
import qualified Distribution.Client.InstallPlan as InstallPlan
import qualified Distribution.Client.Utils.Json as J
import qualified Distribution.Simple.InstallDirs as InstallDirs
import qualified Distribution.Solver.Types.ComponentDeps as ComponentDeps
import qualified Distribution.Compat.Binary as Binary
import Distribution.Compat.Graph (Graph, Node)
import qualified Distribution.Compat.Graph as Graph
import Distribution.InstalledPackageInfo (InstalledPackageInfo)
import Distribution.Package
import qualified Distribution.PackageDescription as PD
import Distribution.Simple.BuildPaths
( buildInfoPref
, dllExtension
, exeExtension
)
import Distribution.Simple.Compiler
import Distribution.Simple.GHC
( GhcEnvironmentFileEntry (..)
, GhcImplInfo (supportsPkgEnvFiles)
, getImplInfo
, simpleGhcEnvironmentFile
, writeGhcEnvironmentFile
)
import Distribution.Simple.Utils
import Distribution.System
import Distribution.Types.Version
( mkVersion
)
import Distribution.Utils.Path hiding
( (<.>)
, (</>)
)
import Distribution.Verbosity
import Distribution.Client.Compat.Prelude
import Prelude ()
import qualified Data.ByteString.Builder as BB
import qualified Data.ByteString.Lazy as BS
import qualified Data.Map as Map
import qualified Data.Set as Set
import System.FilePath
import System.IO
import Distribution.Simple.Program.GHC (packageDbArgsDb)
writePlanExternalRepresentation
:: DistDirLayout
-> ElaboratedInstallPlan
-> ElaboratedSharedConfig
-> IO ()
writePlanExternalRepresentation :: DistDirLayout
-> ElaboratedInstallPlan -> ElaboratedSharedConfig -> IO ()
writePlanExternalRepresentation
DistDirLayout
distDirLayout
ElaboratedInstallPlan
elaboratedInstallPlan
ElaboratedSharedConfig
elaboratedSharedConfig =
String -> ByteString -> IO ()
writeFileAtomic (DistDirLayout -> String -> String
distProjectCacheFile DistDirLayout
distDirLayout String
"plan.json")
(ByteString -> IO ()) -> ByteString -> IO ()
forall a b. (a -> b) -> a -> b
$ Builder -> ByteString
BB.toLazyByteString
(Builder -> ByteString)
-> (Value -> Builder) -> Value -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Value -> Builder
forall a. ToJSON a => a -> Builder
J.encodeToBuilder
(Value -> ByteString) -> Value -> ByteString
forall a b. (a -> b) -> a -> b
$ DistDirLayout
-> ElaboratedInstallPlan -> ElaboratedSharedConfig -> Value
encodePlanAsJson DistDirLayout
distDirLayout ElaboratedInstallPlan
elaboratedInstallPlan ElaboratedSharedConfig
elaboratedSharedConfig
encodePlanAsJson :: DistDirLayout -> ElaboratedInstallPlan -> ElaboratedSharedConfig -> J.Value
encodePlanAsJson :: DistDirLayout
-> ElaboratedInstallPlan -> ElaboratedSharedConfig -> Value
encodePlanAsJson DistDirLayout
distDirLayout ElaboratedInstallPlan
elaboratedInstallPlan ElaboratedSharedConfig
elaboratedSharedConfig =
[Pair] -> Value
J.object
[ String
"cabal-version" String -> Value -> Pair
forall v. ToJSON v => String -> v -> Pair
J..= Version -> Value
forall a. Pretty a => a -> Value
jdisplay Version
cabalInstallVersion
, String
"cabal-lib-version" String -> Value -> Pair
forall v. ToJSON v => String -> v -> Pair
J..= Version -> Value
forall a. Pretty a => a -> Value
jdisplay Version
cabalVersion
, String
"compiler-id"
String -> Value -> Pair
forall v. ToJSON v => String -> v -> Pair
J..= (String -> Value
J.String (String -> Value)
-> (ElaboratedSharedConfig -> String)
-> ElaboratedSharedConfig
-> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Compiler -> String
showCompilerId (Compiler -> String)
-> (ElaboratedSharedConfig -> Compiler)
-> ElaboratedSharedConfig
-> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ElaboratedSharedConfig -> Compiler
pkgConfigCompiler)
ElaboratedSharedConfig
elaboratedSharedConfig
, String
"os" String -> Value -> Pair
forall v. ToJSON v => String -> v -> Pair
J..= OS -> Value
forall a. Pretty a => a -> Value
jdisplay OS
os
, String
"arch" String -> Value -> Pair
forall v. ToJSON v => String -> v -> Pair
J..= Arch -> Value
forall a. Pretty a => a -> Value
jdisplay Arch
arch
, String
"install-plan" String -> [Value] -> Pair
forall v. ToJSON v => String -> v -> Pair
J..= ElaboratedInstallPlan -> [Value]
installPlanToJ ElaboratedInstallPlan
elaboratedInstallPlan
]
where
plat :: Platform
plat :: Platform
plat@(Platform Arch
arch OS
os) = ElaboratedSharedConfig -> Platform
pkgConfigPlatform ElaboratedSharedConfig
elaboratedSharedConfig
installPlanToJ :: ElaboratedInstallPlan -> [J.Value]
installPlanToJ :: ElaboratedInstallPlan -> [Value]
installPlanToJ = (ElaboratedPlanPackage -> Value)
-> [ElaboratedPlanPackage] -> [Value]
forall a b. (a -> b) -> [a] -> [b]
map ElaboratedPlanPackage -> Value
planPackageToJ ([ElaboratedPlanPackage] -> [Value])
-> (ElaboratedInstallPlan -> [ElaboratedPlanPackage])
-> ElaboratedInstallPlan
-> [Value]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ElaboratedInstallPlan -> [ElaboratedPlanPackage]
forall ipkg srcpkg.
GenericInstallPlan ipkg srcpkg -> [GenericPlanPackage ipkg srcpkg]
InstallPlan.toList
planPackageToJ :: ElaboratedPlanPackage -> J.Value
planPackageToJ :: ElaboratedPlanPackage -> Value
planPackageToJ ElaboratedPlanPackage
pkg =
case ElaboratedPlanPackage
pkg of
InstallPlan.PreExisting InstalledPackageInfo
ipi -> InstalledPackageInfo -> Value
installedPackageInfoToJ InstalledPackageInfo
ipi
InstallPlan.Configured ElaboratedConfiguredPackage
elab -> Bool -> ElaboratedConfiguredPackage -> Value
elaboratedPackageToJ Bool
False ElaboratedConfiguredPackage
elab
InstallPlan.Installed ElaboratedConfiguredPackage
elab -> Bool -> ElaboratedConfiguredPackage -> Value
elaboratedPackageToJ Bool
True ElaboratedConfiguredPackage
elab
installedPackageInfoToJ :: InstalledPackageInfo -> J.Value
installedPackageInfoToJ :: InstalledPackageInfo -> Value
installedPackageInfoToJ InstalledPackageInfo
ipi =
[Pair] -> Value
J.object
[ String
"type" String -> Value -> Pair
forall v. ToJSON v => String -> v -> Pair
J..= String -> Value
J.String String
"pre-existing"
, String
"id" String -> Value -> Pair
forall v. ToJSON v => String -> v -> Pair
J..= (UnitId -> Value
forall a. Pretty a => a -> Value
jdisplay (UnitId -> Value)
-> (InstalledPackageInfo -> UnitId)
-> InstalledPackageInfo
-> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. InstalledPackageInfo -> UnitId
forall pkg. HasUnitId pkg => pkg -> UnitId
installedUnitId) InstalledPackageInfo
ipi
, String
"pkg-name" String -> Value -> Pair
forall v. ToJSON v => String -> v -> Pair
J..= (PackageName -> Value
forall a. Pretty a => a -> Value
jdisplay (PackageName -> Value)
-> (InstalledPackageInfo -> PackageName)
-> InstalledPackageInfo
-> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PackageIdentifier -> PackageName
pkgName (PackageIdentifier -> PackageName)
-> (InstalledPackageInfo -> PackageIdentifier)
-> InstalledPackageInfo
-> PackageName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. InstalledPackageInfo -> PackageIdentifier
forall pkg. Package pkg => pkg -> PackageIdentifier
packageId) InstalledPackageInfo
ipi
, String
"pkg-version" String -> Value -> Pair
forall v. ToJSON v => String -> v -> Pair
J..= (Version -> Value
forall a. Pretty a => a -> Value
jdisplay (Version -> Value)
-> (InstalledPackageInfo -> Version)
-> InstalledPackageInfo
-> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PackageIdentifier -> Version
pkgVersion (PackageIdentifier -> Version)
-> (InstalledPackageInfo -> PackageIdentifier)
-> InstalledPackageInfo
-> Version
forall b c a. (b -> c) -> (a -> b) -> a -> c
. InstalledPackageInfo -> PackageIdentifier
forall pkg. Package pkg => pkg -> PackageIdentifier
packageId) InstalledPackageInfo
ipi
, String
"depends" String -> [Value] -> Pair
forall v. ToJSON v => String -> v -> Pair
J..= (UnitId -> Value) -> [UnitId] -> [Value]
forall a b. (a -> b) -> [a] -> [b]
map UnitId -> Value
forall a. Pretty a => a -> Value
jdisplay (InstalledPackageInfo -> [UnitId]
forall pkg. PackageInstalled pkg => pkg -> [UnitId]
installedDepends InstalledPackageInfo
ipi)
]
elaboratedPackageToJ :: Bool -> ElaboratedConfiguredPackage -> J.Value
elaboratedPackageToJ :: Bool -> ElaboratedConfiguredPackage -> Value
elaboratedPackageToJ Bool
isInstalled ElaboratedConfiguredPackage
elab =
[Pair] -> Value
J.object ([Pair] -> Value) -> [Pair] -> Value
forall a b. (a -> b) -> a -> b
$
[ String
"type"
String -> Value -> Pair
forall v. ToJSON v => String -> v -> Pair
J..= String -> Value
J.String
( if Bool
isInstalled
then String
"installed"
else String
"configured"
)
, String
"id" String -> Value -> Pair
forall v. ToJSON v => String -> v -> Pair
J..= (UnitId -> Value
forall a. Pretty a => a -> Value
jdisplay (UnitId -> Value)
-> (ElaboratedConfiguredPackage -> UnitId)
-> ElaboratedConfiguredPackage
-> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ElaboratedConfiguredPackage -> UnitId
forall pkg. HasUnitId pkg => pkg -> UnitId
installedUnitId) ElaboratedConfiguredPackage
elab
, String
"pkg-name" String -> Value -> Pair
forall v. ToJSON v => String -> v -> Pair
J..= (PackageName -> Value
forall a. Pretty a => a -> Value
jdisplay (PackageName -> Value)
-> (ElaboratedConfiguredPackage -> PackageName)
-> ElaboratedConfiguredPackage
-> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PackageIdentifier -> PackageName
pkgName (PackageIdentifier -> PackageName)
-> (ElaboratedConfiguredPackage -> PackageIdentifier)
-> ElaboratedConfiguredPackage
-> PackageName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ElaboratedConfiguredPackage -> PackageIdentifier
forall pkg. Package pkg => pkg -> PackageIdentifier
packageId) ElaboratedConfiguredPackage
elab
, String
"pkg-version" String -> Value -> Pair
forall v. ToJSON v => String -> v -> Pair
J..= (Version -> Value
forall a. Pretty a => a -> Value
jdisplay (Version -> Value)
-> (ElaboratedConfiguredPackage -> Version)
-> ElaboratedConfiguredPackage
-> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PackageIdentifier -> Version
pkgVersion (PackageIdentifier -> Version)
-> (ElaboratedConfiguredPackage -> PackageIdentifier)
-> ElaboratedConfiguredPackage
-> Version
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ElaboratedConfiguredPackage -> PackageIdentifier
forall pkg. Package pkg => pkg -> PackageIdentifier
packageId) ElaboratedConfiguredPackage
elab
, String
"flags"
String -> Value -> Pair
forall v. ToJSON v => String -> v -> Pair
J..= [Pair] -> Value
J.object
[ FlagName -> String
PD.unFlagName FlagName
fn String -> Bool -> Pair
forall v. ToJSON v => String -> v -> Pair
J..= Bool
v
| (FlagName
fn, Bool
v) <- FlagAssignment -> [(FlagName, Bool)]
PD.unFlagAssignment (ElaboratedConfiguredPackage -> FlagAssignment
elabFlagAssignment ElaboratedConfiguredPackage
elab)
]
, String
"style" String -> Value -> Pair
forall v. ToJSON v => String -> v -> Pair
J..= String -> Value
J.String (Bool -> BuildStyle -> String
style2str (ElaboratedConfiguredPackage -> Bool
elabLocalToProject ElaboratedConfiguredPackage
elab) (ElaboratedConfiguredPackage -> BuildStyle
elabBuildStyle ElaboratedConfiguredPackage
elab))
, String
"pkg-src" String -> Value -> Pair
forall v. ToJSON v => String -> v -> Pair
J..= PackageLocation (Maybe String) -> Value
packageLocationToJ (ElaboratedConfiguredPackage -> PackageLocation (Maybe String)
elabPkgSourceLocation ElaboratedConfiguredPackage
elab)
]
[Pair] -> [Pair] -> [Pair]
forall a. [a] -> [a] -> [a]
++ [ String
"pkg-cabal-sha256" String -> Value -> Pair
forall v. ToJSON v => String -> v -> Pair
J..= String -> Value
J.String (HashValue -> String
showHashValue HashValue
hash)
| Just HashValue
hash <- [(ByteString -> HashValue) -> Maybe ByteString -> Maybe HashValue
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ByteString -> HashValue
hashValue (ElaboratedConfiguredPackage -> Maybe ByteString
elabPkgDescriptionOverride ElaboratedConfiguredPackage
elab)]
]
[Pair] -> [Pair] -> [Pair]
forall a. [a] -> [a] -> [a]
++ [ String
"pkg-src-sha256" String -> Value -> Pair
forall v. ToJSON v => String -> v -> Pair
J..= String -> Value
J.String (HashValue -> String
showHashValue HashValue
hash)
| Just HashValue
hash <- [ElaboratedConfiguredPackage -> Maybe HashValue
elabPkgSourceHash ElaboratedConfiguredPackage
elab]
]
[Pair] -> [Pair] -> [Pair]
forall a. [a] -> [a] -> [a]
++ ( case ElaboratedConfiguredPackage -> BuildStyle
elabBuildStyle ElaboratedConfiguredPackage
elab of
BuildInplaceOnly{} ->
[String
"dist-dir" String -> Value -> Pair
forall v. ToJSON v => String -> v -> Pair
J..= String -> Value
J.String String
dist_dir] [Pair] -> [Pair] -> [Pair]
forall a. [a] -> [a] -> [a]
++ [Pair
buildInfoFileLocation]
BuildStyle
BuildAndInstall ->
[]
)
[Pair] -> [Pair] -> [Pair]
forall a. [a] -> [a] -> [a]
++ case ElaboratedConfiguredPackage -> ElaboratedPackageOrComponent
elabPkgOrComp ElaboratedConfiguredPackage
elab of
ElabPackage ElaboratedPackage
pkg ->
let components :: Value
components =
[Pair] -> Value
J.object ([Pair] -> Value) -> [Pair] -> Value
forall a b. (a -> b) -> a -> b
$
[ Component -> String
comp2str Component
c
String -> Value -> Pair
forall v. ToJSON v => String -> v -> Pair
J..= [Pair] -> Value
J.object
( [ String
"depends" String -> [Value] -> Pair
forall v. ToJSON v => String -> v -> Pair
J..= (ConfiguredId -> Value) -> [ConfiguredId] -> [Value]
forall a b. (a -> b) -> [a] -> [b]
map (ComponentId -> Value
forall a. Pretty a => a -> Value
jdisplay (ComponentId -> Value)
-> (ConfiguredId -> ComponentId) -> ConfiguredId -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ConfiguredId -> ComponentId
confInstId) (((ConfiguredId, Bool) -> ConfiguredId)
-> [(ConfiguredId, Bool)] -> [ConfiguredId]
forall a b. (a -> b) -> [a] -> [b]
map (ConfiguredId, Bool) -> ConfiguredId
forall a b. (a, b) -> a
fst [(ConfiguredId, Bool)]
ldeps)
, String
"exe-depends" String -> [Value] -> Pair
forall v. ToJSON v => String -> v -> Pair
J..= (ConfiguredId -> Value) -> [ConfiguredId] -> [Value]
forall a b. (a -> b) -> [a] -> [b]
map (ComponentId -> Value
forall a. Pretty a => a -> Value
jdisplay (ComponentId -> Value)
-> (ConfiguredId -> ComponentId) -> ConfiguredId -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ConfiguredId -> ComponentId
confInstId) [ConfiguredId]
edeps
]
[Pair] -> [Pair] -> [Pair]
forall a. [a] -> [a] -> [a]
++ Component -> [Pair]
bin_file Component
c
)
| (Component
c, ([(ConfiguredId, Bool)]
ldeps, [ConfiguredId]
edeps)) <-
ComponentDeps ([(ConfiguredId, Bool)], [ConfiguredId])
-> [(Component, ([(ConfiguredId, Bool)], [ConfiguredId]))]
forall a. ComponentDeps a -> [ComponentDep a]
ComponentDeps.toList (ComponentDeps ([(ConfiguredId, Bool)], [ConfiguredId])
-> [(Component, ([(ConfiguredId, Bool)], [ConfiguredId]))])
-> ComponentDeps ([(ConfiguredId, Bool)], [ConfiguredId])
-> [(Component, ([(ConfiguredId, Bool)], [ConfiguredId]))]
forall a b. (a -> b) -> a -> b
$
ComponentDeps [(ConfiguredId, Bool)]
-> ComponentDeps [ConfiguredId]
-> ComponentDeps ([(ConfiguredId, Bool)], [ConfiguredId])
forall a b.
(Monoid a, Monoid b) =>
ComponentDeps a -> ComponentDeps b -> ComponentDeps (a, b)
ComponentDeps.zip
(ElaboratedPackage -> ComponentDeps [(ConfiguredId, Bool)]
pkgLibDependencies ElaboratedPackage
pkg)
(ElaboratedPackage -> ComponentDeps [ConfiguredId]
pkgExeDependencies ElaboratedPackage
pkg)
]
in [String
"components" String -> Value -> Pair
forall v. ToJSON v => String -> v -> Pair
J..= Value
components]
ElabComponent ElaboratedComponent
comp ->
[ String
"depends" String -> [Value] -> Pair
forall v. ToJSON v => String -> v -> Pair
J..= (ConfiguredId -> Value) -> [ConfiguredId] -> [Value]
forall a b. (a -> b) -> [a] -> [b]
map (ComponentId -> Value
forall a. Pretty a => a -> Value
jdisplay (ComponentId -> Value)
-> (ConfiguredId -> ComponentId) -> ConfiguredId -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ConfiguredId -> ComponentId
confInstId) (((ConfiguredId, Bool) -> ConfiguredId)
-> [(ConfiguredId, Bool)] -> [ConfiguredId]
forall a b. (a -> b) -> [a] -> [b]
map (ConfiguredId, Bool) -> ConfiguredId
forall a b. (a, b) -> a
fst ([(ConfiguredId, Bool)] -> [ConfiguredId])
-> [(ConfiguredId, Bool)] -> [ConfiguredId]
forall a b. (a -> b) -> a -> b
$ ElaboratedConfiguredPackage -> [(ConfiguredId, Bool)]
elabLibDependencies ElaboratedConfiguredPackage
elab)
, String
"exe-depends" String -> [Value] -> Pair
forall v. ToJSON v => String -> v -> Pair
J..= (ComponentId -> Value) -> [ComponentId] -> [Value]
forall a b. (a -> b) -> [a] -> [b]
map ComponentId -> Value
forall a. Pretty a => a -> Value
jdisplay (ElaboratedConfiguredPackage -> [ComponentId]
elabExeDependencies ElaboratedConfiguredPackage
elab)
, String
"component-name" String -> Value -> Pair
forall v. ToJSON v => String -> v -> Pair
J..= String -> Value
J.String (Component -> String
comp2str (ElaboratedComponent -> Component
compSolverName ElaboratedComponent
comp))
]
[Pair] -> [Pair] -> [Pair]
forall a. [a] -> [a] -> [a]
++ Component -> [Pair]
bin_file (ElaboratedComponent -> Component
compSolverName ElaboratedComponent
comp)
where
buildInfoFileLocation :: J.Pair
buildInfoFileLocation :: Pair
buildInfoFileLocation
| ElaboratedConfiguredPackage -> Version
elabSetupScriptCliVersion ElaboratedConfiguredPackage
elab Version -> Version -> Bool
forall a. Ord a => a -> a -> Bool
< [Int] -> Version
mkVersion [Int
3, Int
7, Int
0, Int
0] =
String
"build-info" String -> Value -> Pair
forall v. ToJSON v => String -> v -> Pair
J..= Value
J.Null
| Bool
otherwise =
String
"build-info" String -> Value -> Pair
forall v. ToJSON v => String -> v -> Pair
J..= String -> Value
J.String (SymbolicPathX 'AllowAbsolute Any 'File -> String
forall (allowAbsolute :: AllowAbsolute) from (to :: FileOrDir).
SymbolicPathX allowAbsolute from to -> String
getSymbolicPath (SymbolicPathX 'AllowAbsolute Any 'File -> String)
-> SymbolicPathX 'AllowAbsolute Any 'File -> String
forall a b. (a -> b) -> a -> b
$ SymbolicPath Any ('Dir Dist)
-> SymbolicPathX 'AllowAbsolute Any 'File
forall root.
SymbolicPath root ('Dir Dist) -> SymbolicPath root 'File
buildInfoPref (SymbolicPath Any ('Dir Dist)
-> SymbolicPathX 'AllowAbsolute Any 'File)
-> SymbolicPath Any ('Dir Dist)
-> SymbolicPathX 'AllowAbsolute Any 'File
forall a b. (a -> b) -> a -> b
$ String -> SymbolicPath Any ('Dir Dist)
forall from (to :: FileOrDir). String -> SymbolicPath from to
makeSymbolicPath String
dist_dir)
packageLocationToJ :: PackageLocation (Maybe FilePath) -> J.Value
packageLocationToJ :: PackageLocation (Maybe String) -> Value
packageLocationToJ PackageLocation (Maybe String)
pkgloc =
case PackageLocation (Maybe String)
pkgloc of
LocalUnpackedPackage String
local ->
[Pair] -> Value
J.object
[ String
"type" String -> Value -> Pair
forall v. ToJSON v => String -> v -> Pair
J..= String -> Value
J.String String
"local"
, String
"path" String -> Value -> Pair
forall v. ToJSON v => String -> v -> Pair
J..= String -> Value
J.String String
local
]
LocalTarballPackage String
local ->
[Pair] -> Value
J.object
[ String
"type" String -> Value -> Pair
forall v. ToJSON v => String -> v -> Pair
J..= String -> Value
J.String String
"local-tar"
, String
"path" String -> Value -> Pair
forall v. ToJSON v => String -> v -> Pair
J..= String -> Value
J.String String
local
]
RemoteTarballPackage URI
uri Maybe String
_ ->
[Pair] -> Value
J.object
[ String
"type" String -> Value -> Pair
forall v. ToJSON v => String -> v -> Pair
J..= String -> Value
J.String String
"remote-tar"
, String
"uri" String -> Value -> Pair
forall v. ToJSON v => String -> v -> Pair
J..= String -> Value
J.String (URI -> String
forall a. Show a => a -> String
show URI
uri)
]
RepoTarballPackage Repo
repo PackageIdentifier
_ Maybe String
_ ->
[Pair] -> Value
J.object
[ String
"type" String -> Value -> Pair
forall v. ToJSON v => String -> v -> Pair
J..= String -> Value
J.String String
"repo-tar"
, String
"repo" String -> Value -> Pair
forall v. ToJSON v => String -> v -> Pair
J..= Repo -> Value
repoToJ Repo
repo
]
RemoteSourceRepoPackage SourceRepoMaybe
srcRepo Maybe String
_ ->
[Pair] -> Value
J.object
[ String
"type" String -> Value -> Pair
forall v. ToJSON v => String -> v -> Pair
J..= String -> Value
J.String String
"source-repo"
, String
"source-repo" String -> Value -> Pair
forall v. ToJSON v => String -> v -> Pair
J..= SourceRepoMaybe -> Value
sourceRepoToJ SourceRepoMaybe
srcRepo
]
repoToJ :: Repo -> J.Value
repoToJ :: Repo -> Value
repoToJ Repo
repo =
case Repo
repo of
RepoLocalNoIndex{String
LocalRepo
repoLocal :: LocalRepo
repoLocalDir :: String
repoLocal :: Repo -> LocalRepo
repoLocalDir :: Repo -> String
..} ->
[Pair] -> Value
J.object
[ String
"type" String -> Value -> Pair
forall v. ToJSON v => String -> v -> Pair
J..= String -> Value
J.String String
"local-repo-no-index"
, String
"path" String -> Value -> Pair
forall v. ToJSON v => String -> v -> Pair
J..= String -> Value
J.String String
repoLocalDir
]
RepoRemote{String
RemoteRepo
repoLocalDir :: Repo -> String
repoRemote :: RemoteRepo
repoLocalDir :: String
repoRemote :: Repo -> RemoteRepo
..} ->
[Pair] -> Value
J.object
[ String
"type" String -> Value -> Pair
forall v. ToJSON v => String -> v -> Pair
J..= String -> Value
J.String String
"remote-repo"
, String
"uri" String -> Value -> Pair
forall v. ToJSON v => String -> v -> Pair
J..= String -> Value
J.String (URI -> String
forall a. Show a => a -> String
show (RemoteRepo -> URI
remoteRepoURI RemoteRepo
repoRemote))
]
RepoSecure{String
RemoteRepo
repoLocalDir :: Repo -> String
repoRemote :: Repo -> RemoteRepo
repoRemote :: RemoteRepo
repoLocalDir :: String
..} ->
[Pair] -> Value
J.object
[ String
"type" String -> Value -> Pair
forall v. ToJSON v => String -> v -> Pair
J..= String -> Value
J.String String
"secure-repo"
, String
"uri" String -> Value -> Pair
forall v. ToJSON v => String -> v -> Pair
J..= String -> Value
J.String (URI -> String
forall a. Show a => a -> String
show (RemoteRepo -> URI
remoteRepoURI RemoteRepo
repoRemote))
]
sourceRepoToJ :: SourceRepoMaybe -> J.Value
sourceRepoToJ :: SourceRepoMaybe -> Value
sourceRepoToJ SourceRepositoryPackage{String
[String]
Maybe String
RepoType
srpType :: RepoType
srpLocation :: String
srpTag :: Maybe String
srpBranch :: Maybe String
srpSubdir :: Maybe String
srpCommand :: [String]
srpType :: forall (f :: * -> *). SourceRepositoryPackage f -> RepoType
srpLocation :: forall (f :: * -> *). SourceRepositoryPackage f -> String
srpTag :: forall (f :: * -> *). SourceRepositoryPackage f -> Maybe String
srpBranch :: forall (f :: * -> *). SourceRepositoryPackage f -> Maybe String
srpSubdir :: forall (f :: * -> *). SourceRepositoryPackage f -> f String
srpCommand :: forall (f :: * -> *). SourceRepositoryPackage f -> [String]
..} =
[Pair] -> Value
J.object ([Pair] -> Value) -> [Pair] -> Value
forall a b. (a -> b) -> a -> b
$
(Pair -> Bool) -> [Pair] -> [Pair]
forall a. (a -> Bool) -> [a] -> [a]
filter ((Value -> Value -> Bool
forall a. Eq a => a -> a -> Bool
/= Value
J.Null) (Value -> Bool) -> (Pair -> Value) -> Pair -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Pair -> Value
forall a b. (a, b) -> b
snd) ([Pair] -> [Pair]) -> [Pair] -> [Pair]
forall a b. (a -> b) -> a -> b
$
[ String
"type" String -> Value -> Pair
forall v. ToJSON v => String -> v -> Pair
J..= RepoType -> Value
forall a. Pretty a => a -> Value
jdisplay RepoType
srpType
, String
"location" String -> Value -> Pair
forall v. ToJSON v => String -> v -> Pair
J..= String -> Value
J.String String
srpLocation
, String
"branch" String -> Maybe Value -> Pair
forall v. ToJSON v => String -> v -> Pair
J..= (String -> Value) -> Maybe String -> Maybe Value
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap String -> Value
J.String Maybe String
srpBranch
, String
"tag" String -> Maybe Value -> Pair
forall v. ToJSON v => String -> v -> Pair
J..= (String -> Value) -> Maybe String -> Maybe Value
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap String -> Value
J.String Maybe String
srpTag
, String
"subdir" String -> Maybe Value -> Pair
forall v. ToJSON v => String -> v -> Pair
J..= (String -> Value) -> Maybe String -> Maybe Value
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap String -> Value
J.String Maybe String
srpSubdir
]
dist_dir :: FilePath
dist_dir :: String
dist_dir =
DistDirLayout -> DistDirParams -> String
distBuildDirectory
DistDirLayout
distDirLayout
(ElaboratedSharedConfig
-> ElaboratedConfiguredPackage -> DistDirParams
elabDistDirParams ElaboratedSharedConfig
elaboratedSharedConfig ElaboratedConfiguredPackage
elab)
bin_file :: ComponentDeps.Component -> [J.Pair]
bin_file :: Component -> [Pair]
bin_file Component
c = case Component
c of
ComponentDeps.ComponentExe UnqualComponentName
s -> UnqualComponentName -> [Pair]
forall {p}. Pretty p => p -> [Pair]
bin_file' UnqualComponentName
s
ComponentDeps.ComponentTest UnqualComponentName
s -> UnqualComponentName -> [Pair]
forall {p}. Pretty p => p -> [Pair]
bin_file' UnqualComponentName
s
ComponentDeps.ComponentBench UnqualComponentName
s -> UnqualComponentName -> [Pair]
forall {p}. Pretty p => p -> [Pair]
bin_file' UnqualComponentName
s
ComponentDeps.ComponentFLib UnqualComponentName
s -> UnqualComponentName -> [Pair]
forall a. (Pretty a, Show a) => a -> [Pair]
flib_file' UnqualComponentName
s
Component
_ -> []
bin_file' :: p -> [Pair]
bin_file' p
s =
[String
"bin-file" String -> Value -> Pair
forall v. ToJSON v => String -> v -> Pair
J..= String -> Value
J.String String
bin]
where
bin :: String
bin =
if BuildStyle -> Bool
isInplaceBuildStyle (ElaboratedConfiguredPackage -> BuildStyle
elabBuildStyle ElaboratedConfiguredPackage
elab)
then String
dist_dir String -> String -> String
</> String
"build" String -> String -> String
</> p -> String
forall a. Pretty a => a -> String
prettyShow p
s String -> String -> String
</> p -> String
forall a. Pretty a => a -> String
prettyShow p
s String -> String -> String
<.> Platform -> String
exeExtension Platform
plat
else InstallDirs String -> String
forall dir. InstallDirs dir -> dir
InstallDirs.bindir (ElaboratedConfiguredPackage -> InstallDirs String
elabInstallDirs ElaboratedConfiguredPackage
elab) String -> String -> String
</> p -> String
forall a. Pretty a => a -> String
prettyShow p
s String -> String -> String
<.> Platform -> String
exeExtension Platform
plat
flib_file' :: (Pretty a, Show a) => a -> [J.Pair]
flib_file' :: forall a. (Pretty a, Show a) => a -> [Pair]
flib_file' a
s =
[String
"bin-file" String -> Value -> Pair
forall v. ToJSON v => String -> v -> Pair
J..= String -> Value
J.String String
bin]
where
bin :: String
bin =
if BuildStyle -> Bool
isInplaceBuildStyle (ElaboratedConfiguredPackage -> BuildStyle
elabBuildStyle ElaboratedConfiguredPackage
elab)
then String
dist_dir String -> String -> String
</> String
"build" String -> String -> String
</> a -> String
forall a. Pretty a => a -> String
prettyShow a
s String -> String -> String
</> (String
"lib" String -> String -> String
forall a. [a] -> [a] -> [a]
++ a -> String
forall a. Pretty a => a -> String
prettyShow a
s) String -> String -> String
<.> Platform -> String
dllExtension Platform
plat
else InstallDirs String -> String
forall dir. InstallDirs dir -> dir
InstallDirs.bindir (ElaboratedConfiguredPackage -> InstallDirs String
elabInstallDirs ElaboratedConfiguredPackage
elab) String -> String -> String
</> (String
"lib" String -> String -> String
forall a. [a] -> [a] -> [a]
++ a -> String
forall a. Pretty a => a -> String
prettyShow a
s) String -> String -> String
<.> Platform -> String
dllExtension Platform
plat
comp2str :: ComponentDeps.Component -> String
comp2str :: Component -> String
comp2str = Component -> String
forall a. Pretty a => a -> String
prettyShow
style2str :: Bool -> BuildStyle -> String
style2str :: Bool -> BuildStyle -> String
style2str Bool
True BuildStyle
_ = String
"local"
style2str Bool
False (BuildInplaceOnly MemoryOrDisk
OnDisk) = String
"inplace"
style2str Bool
False (BuildInplaceOnly MemoryOrDisk
InMemory) = String
"interactive"
style2str Bool
False BuildStyle
BuildAndInstall = String
"global"
jdisplay :: Pretty a => a -> J.Value
jdisplay :: forall a. Pretty a => a -> Value
jdisplay = String -> Value
J.String (String -> Value) -> (a -> String) -> a -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> String
forall a. Pretty a => a -> String
prettyShow
type PackageIdSet = Set UnitId
type PackagesUpToDate = PackageIdSet
data PostBuildProjectStatus = PostBuildProjectStatus
{ PostBuildProjectStatus -> PackagesUpToDate
packagesDefinitelyUpToDate :: PackageIdSet
, PostBuildProjectStatus -> PackagesUpToDate
packagesProbablyUpToDate :: PackageIdSet
, PostBuildProjectStatus -> PackagesUpToDate
packagesOutOfDate :: PackageIdSet
, PostBuildProjectStatus -> PackagesUpToDate
packagesInvalidByChangedLibDeps :: PackageIdSet
, PostBuildProjectStatus -> PackagesUpToDate
packagesInvalidByFailedBuild :: PackageIdSet
, PostBuildProjectStatus -> Graph (Node UnitId ElaboratedPlanPackage)
packagesLibDepGraph :: Graph (Node UnitId ElaboratedPlanPackage)
, PostBuildProjectStatus -> PackagesUpToDate
packagesBuildLocal :: PackageIdSet
, PostBuildProjectStatus -> PackagesUpToDate
packagesBuildInplace :: PackageIdSet
, PostBuildProjectStatus -> PackagesUpToDate
packagesAlreadyInStore :: PackageIdSet
}
postBuildProjectStatus
:: ElaboratedInstallPlan
-> PackagesUpToDate
-> BuildStatusMap
-> BuildOutcomes
-> PostBuildProjectStatus
postBuildProjectStatus :: ElaboratedInstallPlan
-> PackagesUpToDate
-> BuildStatusMap
-> BuildOutcomes
-> PostBuildProjectStatus
postBuildProjectStatus
ElaboratedInstallPlan
plan
PackagesUpToDate
previousPackagesUpToDate
BuildStatusMap
pkgBuildStatus
BuildOutcomes
buildOutcomes =
PostBuildProjectStatus
{ PackagesUpToDate
packagesDefinitelyUpToDate :: PackagesUpToDate
packagesDefinitelyUpToDate :: PackagesUpToDate
packagesDefinitelyUpToDate
, PackagesUpToDate
packagesProbablyUpToDate :: PackagesUpToDate
packagesProbablyUpToDate :: PackagesUpToDate
packagesProbablyUpToDate
, PackagesUpToDate
packagesOutOfDate :: PackagesUpToDate
packagesOutOfDate :: PackagesUpToDate
packagesOutOfDate
, PackagesUpToDate
packagesInvalidByChangedLibDeps :: PackagesUpToDate
packagesInvalidByChangedLibDeps :: PackagesUpToDate
packagesInvalidByChangedLibDeps
, PackagesUpToDate
packagesInvalidByFailedBuild :: PackagesUpToDate
packagesInvalidByFailedBuild :: PackagesUpToDate
packagesInvalidByFailedBuild
,
Graph (Node UnitId ElaboratedPlanPackage)
packagesLibDepGraph :: Graph (Node UnitId ElaboratedPlanPackage)
packagesLibDepGraph :: Graph (Node UnitId ElaboratedPlanPackage)
packagesLibDepGraph
, PackagesUpToDate
packagesBuildLocal :: PackagesUpToDate
packagesBuildLocal :: PackagesUpToDate
packagesBuildLocal
, PackagesUpToDate
packagesBuildInplace :: PackagesUpToDate
packagesBuildInplace :: PackagesUpToDate
packagesBuildInplace
, PackagesUpToDate
packagesAlreadyInStore :: PackagesUpToDate
packagesAlreadyInStore :: PackagesUpToDate
packagesAlreadyInStore
}
where
packagesDefinitelyUpToDate :: PackagesUpToDate
packagesDefinitelyUpToDate =
PackagesUpToDate
packagesUpToDatePreBuild
PackagesUpToDate -> PackagesUpToDate -> PackagesUpToDate
forall a. Ord a => Set a -> Set a -> Set a
`Set.union` PackagesUpToDate
packagesSuccessfulPostBuild
packagesProbablyUpToDate :: PackagesUpToDate
packagesProbablyUpToDate =
PackagesUpToDate
packagesDefinitelyUpToDate
PackagesUpToDate -> PackagesUpToDate -> PackagesUpToDate
forall a. Ord a => Set a -> Set a -> Set a
`Set.union` (PackagesUpToDate
previousPackagesUpToDate' PackagesUpToDate -> PackagesUpToDate -> PackagesUpToDate
forall a. Ord a => Set a -> Set a -> Set a
`Set.difference` PackagesUpToDate
packagesOutOfDatePreBuild)
packagesOutOfDate :: PackagesUpToDate
packagesOutOfDate =
PackagesUpToDate
packagesOutOfDatePreBuild PackagesUpToDate -> PackagesUpToDate -> PackagesUpToDate
forall a. Ord a => Set a -> Set a -> Set a
`Set.difference` PackagesUpToDate
packagesSuccessfulPostBuild
packagesInvalidByChangedLibDeps :: PackagesUpToDate
packagesInvalidByChangedLibDeps =
PackagesUpToDate
packagesDepOnChangedLib PackagesUpToDate -> PackagesUpToDate -> PackagesUpToDate
forall a. Ord a => Set a -> Set a -> Set a
`Set.difference` PackagesUpToDate
packagesSuccessfulPostBuild
packagesInvalidByFailedBuild :: PackagesUpToDate
packagesInvalidByFailedBuild =
PackagesUpToDate
packagesFailurePostBuild
previousPackagesUpToDate' :: PackagesUpToDate
previousPackagesUpToDate' =
PackagesUpToDate -> PackagesUpToDate -> PackagesUpToDate
forall a. Ord a => Set a -> Set a -> Set a
Set.intersection
PackagesUpToDate
previousPackagesUpToDate
(ElaboratedInstallPlan -> PackagesUpToDate
forall ipkg srcpkg.
GenericInstallPlan ipkg srcpkg -> PackagesUpToDate
InstallPlan.keysSet ElaboratedInstallPlan
plan)
packagesUpToDatePreBuild :: PackagesUpToDate
packagesUpToDatePreBuild =
(UnitId -> Bool) -> PackagesUpToDate -> PackagesUpToDate
forall a. (a -> Bool) -> Set a -> Set a
Set.filter
(\UnitId
ipkgid -> Bool -> Bool
not (Bool -> UnitId -> Bool
lookupBuildStatusRequiresBuild Bool
True UnitId
ipkgid))
(ElaboratedInstallPlan -> PackagesUpToDate
forall ipkg srcpkg.
GenericInstallPlan ipkg srcpkg -> PackagesUpToDate
InstallPlan.keysSet ElaboratedInstallPlan
plan)
packagesOutOfDatePreBuild :: PackagesUpToDate
packagesOutOfDatePreBuild =
[UnitId] -> PackagesUpToDate
forall a. Ord a => [a] -> Set a
Set.fromList ([UnitId] -> PackagesUpToDate)
-> ([ElaboratedPlanPackage] -> [UnitId])
-> [ElaboratedPlanPackage]
-> PackagesUpToDate
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ElaboratedPlanPackage -> UnitId)
-> [ElaboratedPlanPackage] -> [UnitId]
forall a b. (a -> b) -> [a] -> [b]
map ElaboratedPlanPackage -> UnitId
forall pkg. HasUnitId pkg => pkg -> UnitId
installedUnitId ([ElaboratedPlanPackage] -> PackagesUpToDate)
-> [ElaboratedPlanPackage] -> PackagesUpToDate
forall a b. (a -> b) -> a -> b
$
ElaboratedInstallPlan -> [UnitId] -> [ElaboratedPlanPackage]
forall ipkg srcpkg.
GenericInstallPlan ipkg srcpkg
-> [UnitId] -> [GenericPlanPackage ipkg srcpkg]
InstallPlan.reverseDependencyClosure
ElaboratedInstallPlan
plan
[ UnitId
ipkgid
| ElaboratedPlanPackage
pkg <- ElaboratedInstallPlan -> [ElaboratedPlanPackage]
forall ipkg srcpkg.
GenericInstallPlan ipkg srcpkg -> [GenericPlanPackage ipkg srcpkg]
InstallPlan.toList ElaboratedInstallPlan
plan
, let ipkgid :: UnitId
ipkgid = ElaboratedPlanPackage -> UnitId
forall pkg. HasUnitId pkg => pkg -> UnitId
installedUnitId ElaboratedPlanPackage
pkg
, Bool -> UnitId -> Bool
lookupBuildStatusRequiresBuild Bool
False UnitId
ipkgid
]
packagesSuccessfulPostBuild :: PackagesUpToDate
packagesSuccessfulPostBuild =
[UnitId] -> PackagesUpToDate
forall a. Ord a => [a] -> Set a
Set.fromList
[UnitId
ikgid | (UnitId
ikgid, Right BuildResult
_) <- BuildOutcomes -> [(UnitId, BuildOutcome)]
forall k a. Map k a -> [(k, a)]
Map.toList BuildOutcomes
buildOutcomes]
packagesFailurePostBuild :: PackagesUpToDate
packagesFailurePostBuild =
[UnitId] -> PackagesUpToDate
forall a. Ord a => [a] -> Set a
Set.fromList
[ UnitId
ikgid
| (UnitId
ikgid, Left BuildFailure
failure) <- BuildOutcomes -> [(UnitId, BuildOutcome)]
forall k a. Map k a -> [(k, a)]
Map.toList BuildOutcomes
buildOutcomes
, case BuildFailure -> BuildFailureReason
buildFailureReason BuildFailure
failure of
DependentFailed PackageIdentifier
_ -> Bool
False
BuildFailureReason
_ -> Bool
True
]
packagesDepOnChangedLib :: PackagesUpToDate
packagesDepOnChangedLib =
[UnitId] -> PackagesUpToDate
forall a. Ord a => [a] -> Set a
Set.fromList ([UnitId] -> PackagesUpToDate)
-> ([Node UnitId ElaboratedPlanPackage] -> [UnitId])
-> [Node UnitId ElaboratedPlanPackage]
-> PackagesUpToDate
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Node UnitId ElaboratedPlanPackage -> UnitId)
-> [Node UnitId ElaboratedPlanPackage] -> [UnitId]
forall a b. (a -> b) -> [a] -> [b]
map Node UnitId ElaboratedPlanPackage -> UnitId
Node UnitId ElaboratedPlanPackage
-> Key (Node UnitId ElaboratedPlanPackage)
forall a. IsNode a => a -> Key a
Graph.nodeKey ([Node UnitId ElaboratedPlanPackage] -> PackagesUpToDate)
-> [Node UnitId ElaboratedPlanPackage] -> PackagesUpToDate
forall a b. (a -> b) -> a -> b
$
[Node UnitId ElaboratedPlanPackage]
-> Maybe [Node UnitId ElaboratedPlanPackage]
-> [Node UnitId ElaboratedPlanPackage]
forall a. a -> Maybe a -> a
fromMaybe (String -> [Node UnitId ElaboratedPlanPackage]
forall a. HasCallStack => String -> a
error String
"packagesBuildStatusAfterBuild: broken dep closure") (Maybe [Node UnitId ElaboratedPlanPackage]
-> [Node UnitId ElaboratedPlanPackage])
-> Maybe [Node UnitId ElaboratedPlanPackage]
-> [Node UnitId ElaboratedPlanPackage]
forall a b. (a -> b) -> a -> b
$
Graph (Node UnitId ElaboratedPlanPackage)
-> [Key (Node UnitId ElaboratedPlanPackage)]
-> Maybe [Node UnitId ElaboratedPlanPackage]
forall a. Graph a -> [Key a] -> Maybe [a]
Graph.revClosure
Graph (Node UnitId ElaboratedPlanPackage)
packagesLibDepGraph
( Map UnitId (BuildStatus, BuildOutcome) -> [UnitId]
Map UnitId (BuildStatus, BuildOutcome)
-> [Key (Node UnitId ElaboratedPlanPackage)]
forall k a. Map k a -> [k]
Map.keys
(Map UnitId (BuildStatus, BuildOutcome)
-> [Key (Node UnitId ElaboratedPlanPackage)])
-> (Map UnitId (BuildStatus, BuildOutcome)
-> Map UnitId (BuildStatus, BuildOutcome))
-> Map UnitId (BuildStatus, BuildOutcome)
-> [Key (Node UnitId ElaboratedPlanPackage)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((BuildStatus, BuildOutcome) -> Bool)
-> Map UnitId (BuildStatus, BuildOutcome)
-> Map UnitId (BuildStatus, BuildOutcome)
forall a k. (a -> Bool) -> Map k a -> Map k a
Map.filter ((BuildStatus -> BuildOutcome -> Bool)
-> (BuildStatus, BuildOutcome) -> Bool
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry BuildStatus -> BuildOutcome -> Bool
buildAttempted)
(Map UnitId (BuildStatus, BuildOutcome)
-> [Key (Node UnitId ElaboratedPlanPackage)])
-> Map UnitId (BuildStatus, BuildOutcome)
-> [Key (Node UnitId ElaboratedPlanPackage)]
forall a b. (a -> b) -> a -> b
$ (BuildStatus -> BuildOutcome -> (BuildStatus, BuildOutcome))
-> BuildStatusMap
-> BuildOutcomes
-> Map UnitId (BuildStatus, BuildOutcome)
forall k a b c.
Ord k =>
(a -> b -> c) -> Map k a -> Map k b -> Map k c
Map.intersectionWith (,) BuildStatusMap
pkgBuildStatus BuildOutcomes
buildOutcomes
)
packagesLibDepGraph :: Graph (Node UnitId ElaboratedPlanPackage)
packagesLibDepGraph :: Graph (Node UnitId ElaboratedPlanPackage)
packagesLibDepGraph =
[Node UnitId ElaboratedPlanPackage]
-> Graph (Node UnitId ElaboratedPlanPackage)
forall a. (IsNode a, Show (Key a)) => [a] -> Graph a
Graph.fromDistinctList
[ ElaboratedPlanPackage
-> UnitId -> [UnitId] -> Node UnitId ElaboratedPlanPackage
forall k a. a -> k -> [k] -> Node k a
Graph.N ElaboratedPlanPackage
pkg (ElaboratedPlanPackage -> UnitId
forall pkg. HasUnitId pkg => pkg -> UnitId
installedUnitId ElaboratedPlanPackage
pkg) [UnitId]
libdeps
| ElaboratedPlanPackage
pkg <- ElaboratedInstallPlan -> [ElaboratedPlanPackage]
forall ipkg srcpkg.
GenericInstallPlan ipkg srcpkg -> [GenericPlanPackage ipkg srcpkg]
InstallPlan.toList ElaboratedInstallPlan
plan
, let libdeps :: [UnitId]
libdeps = case ElaboratedPlanPackage
pkg of
InstallPlan.PreExisting InstalledPackageInfo
ipkg -> InstalledPackageInfo -> [UnitId]
forall pkg. PackageInstalled pkg => pkg -> [UnitId]
installedDepends InstalledPackageInfo
ipkg
InstallPlan.Configured ElaboratedConfiguredPackage
srcpkg -> ElaboratedConfiguredPackage -> [UnitId]
elabLibDeps ElaboratedConfiguredPackage
srcpkg
InstallPlan.Installed ElaboratedConfiguredPackage
srcpkg -> ElaboratedConfiguredPackage -> [UnitId]
elabLibDeps ElaboratedConfiguredPackage
srcpkg
]
elabLibDeps :: ElaboratedConfiguredPackage -> [UnitId]
elabLibDeps :: ElaboratedConfiguredPackage -> [UnitId]
elabLibDeps = (ConfiguredId -> UnitId) -> [ConfiguredId] -> [UnitId]
forall a b. (a -> b) -> [a] -> [b]
map (ComponentId -> UnitId
newSimpleUnitId (ComponentId -> UnitId)
-> (ConfiguredId -> ComponentId) -> ConfiguredId -> UnitId
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ConfiguredId -> ComponentId
confInstId) ([ConfiguredId] -> [UnitId])
-> (ElaboratedConfiguredPackage -> [ConfiguredId])
-> ElaboratedConfiguredPackage
-> [UnitId]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((ConfiguredId, Bool) -> ConfiguredId)
-> [(ConfiguredId, Bool)] -> [ConfiguredId]
forall a b. (a -> b) -> [a] -> [b]
map (ConfiguredId, Bool) -> ConfiguredId
forall a b. (a, b) -> a
fst ([(ConfiguredId, Bool)] -> [ConfiguredId])
-> (ElaboratedConfiguredPackage -> [(ConfiguredId, Bool)])
-> ElaboratedConfiguredPackage
-> [ConfiguredId]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ElaboratedConfiguredPackage -> [(ConfiguredId, Bool)]
elabLibDependencies
buildAttempted :: BuildStatus -> BuildOutcome -> Bool
buildAttempted :: BuildStatus -> BuildOutcome -> Bool
buildAttempted BuildStatus
buildStatus BuildOutcome
_buildOutcome
| Bool -> Bool
not (BuildStatus -> Bool
buildStatusRequiresBuild BuildStatus
buildStatus) =
Bool
False
buildAttempted BuildStatus
_ (Left BuildFailure{BuildFailureReason
buildFailureReason :: BuildFailure -> BuildFailureReason
buildFailureReason :: BuildFailureReason
buildFailureReason})
| DependentFailed PackageIdentifier
_ <- BuildFailureReason
buildFailureReason =
Bool
False
buildAttempted BuildStatus
_ (Left BuildFailure{}) = Bool
True
buildAttempted BuildStatus
_ (Right BuildResult
_) = Bool
True
lookupBuildStatusRequiresBuild :: Bool -> UnitId -> Bool
lookupBuildStatusRequiresBuild :: Bool -> UnitId -> Bool
lookupBuildStatusRequiresBuild Bool
def UnitId
ipkgid =
case UnitId -> BuildStatusMap -> Maybe BuildStatus
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup UnitId
ipkgid BuildStatusMap
pkgBuildStatus of
Maybe BuildStatus
Nothing -> Bool
def
Just BuildStatus
buildStatus -> BuildStatus -> Bool
buildStatusRequiresBuild BuildStatus
buildStatus
packagesBuildLocal :: Set UnitId
packagesBuildLocal :: PackagesUpToDate
packagesBuildLocal =
(ElaboratedPlanPackage -> Bool) -> PackagesUpToDate
selectPlanPackageIdSet ((ElaboratedPlanPackage -> Bool) -> PackagesUpToDate)
-> (ElaboratedPlanPackage -> Bool) -> PackagesUpToDate
forall a b. (a -> b) -> a -> b
$ \ElaboratedPlanPackage
pkg ->
case ElaboratedPlanPackage
pkg of
InstallPlan.PreExisting InstalledPackageInfo
_ -> Bool
False
InstallPlan.Installed ElaboratedConfiguredPackage
_ -> Bool
False
InstallPlan.Configured ElaboratedConfiguredPackage
srcpkg -> ElaboratedConfiguredPackage -> Bool
elabLocalToProject ElaboratedConfiguredPackage
srcpkg
packagesBuildInplace :: Set UnitId
packagesBuildInplace :: PackagesUpToDate
packagesBuildInplace =
(ElaboratedPlanPackage -> Bool) -> PackagesUpToDate
selectPlanPackageIdSet ((ElaboratedPlanPackage -> Bool) -> PackagesUpToDate)
-> (ElaboratedPlanPackage -> Bool) -> PackagesUpToDate
forall a b. (a -> b) -> a -> b
$ \ElaboratedPlanPackage
pkg ->
case ElaboratedPlanPackage
pkg of
InstallPlan.PreExisting InstalledPackageInfo
_ -> Bool
False
InstallPlan.Installed ElaboratedConfiguredPackage
_ -> Bool
False
InstallPlan.Configured ElaboratedConfiguredPackage
srcpkg -> BuildStyle -> Bool
isInplaceBuildStyle (ElaboratedConfiguredPackage -> BuildStyle
elabBuildStyle ElaboratedConfiguredPackage
srcpkg)
packagesAlreadyInStore :: Set UnitId
packagesAlreadyInStore :: PackagesUpToDate
packagesAlreadyInStore =
(ElaboratedPlanPackage -> Bool) -> PackagesUpToDate
selectPlanPackageIdSet ((ElaboratedPlanPackage -> Bool) -> PackagesUpToDate)
-> (ElaboratedPlanPackage -> Bool) -> PackagesUpToDate
forall a b. (a -> b) -> a -> b
$ \ElaboratedPlanPackage
pkg ->
case ElaboratedPlanPackage
pkg of
InstallPlan.PreExisting InstalledPackageInfo
_ -> Bool
True
InstallPlan.Installed ElaboratedConfiguredPackage
_ -> Bool
True
InstallPlan.Configured ElaboratedConfiguredPackage
_ -> Bool
False
selectPlanPackageIdSet
:: ( InstallPlan.GenericPlanPackage InstalledPackageInfo ElaboratedConfiguredPackage
-> Bool
)
-> Set UnitId
selectPlanPackageIdSet :: (ElaboratedPlanPackage -> Bool) -> PackagesUpToDate
selectPlanPackageIdSet ElaboratedPlanPackage -> Bool
p =
Map UnitId ElaboratedPlanPackage -> PackagesUpToDate
forall k a. Map k a -> Set k
Map.keysSet
(Map UnitId ElaboratedPlanPackage -> PackagesUpToDate)
-> (Map UnitId ElaboratedPlanPackage
-> Map UnitId ElaboratedPlanPackage)
-> Map UnitId ElaboratedPlanPackage
-> PackagesUpToDate
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ElaboratedPlanPackage -> Bool)
-> Map UnitId ElaboratedPlanPackage
-> Map UnitId ElaboratedPlanPackage
forall a k. (a -> Bool) -> Map k a -> Map k a
Map.filter ElaboratedPlanPackage -> Bool
p
(Map UnitId ElaboratedPlanPackage -> PackagesUpToDate)
-> Map UnitId ElaboratedPlanPackage -> PackagesUpToDate
forall a b. (a -> b) -> a -> b
$ ElaboratedInstallPlan -> Map UnitId ElaboratedPlanPackage
forall ipkg srcpkg.
GenericInstallPlan ipkg srcpkg
-> Map UnitId (GenericPlanPackage ipkg srcpkg)
InstallPlan.toMap ElaboratedInstallPlan
plan
updatePostBuildProjectStatus
:: Verbosity
-> DistDirLayout
-> ElaboratedInstallPlan
-> BuildStatusMap
-> BuildOutcomes
-> IO PostBuildProjectStatus
updatePostBuildProjectStatus :: Verbosity
-> DistDirLayout
-> ElaboratedInstallPlan
-> BuildStatusMap
-> BuildOutcomes
-> IO PostBuildProjectStatus
updatePostBuildProjectStatus
Verbosity
verbosity
DistDirLayout
distDirLayout
ElaboratedInstallPlan
elaboratedInstallPlan
BuildStatusMap
pkgsBuildStatus
BuildOutcomes
buildOutcomes = do
PackagesUpToDate
previousUpToDate <- DistDirLayout -> IO PackagesUpToDate
readPackagesUpToDateCacheFile DistDirLayout
distDirLayout
let currentBuildStatus :: PostBuildProjectStatus
currentBuildStatus@PostBuildProjectStatus{PackagesUpToDate
Graph (Node UnitId ElaboratedPlanPackage)
packagesDefinitelyUpToDate :: PostBuildProjectStatus -> PackagesUpToDate
packagesProbablyUpToDate :: PostBuildProjectStatus -> PackagesUpToDate
packagesOutOfDate :: PostBuildProjectStatus -> PackagesUpToDate
packagesInvalidByChangedLibDeps :: PostBuildProjectStatus -> PackagesUpToDate
packagesInvalidByFailedBuild :: PostBuildProjectStatus -> PackagesUpToDate
packagesLibDepGraph :: PostBuildProjectStatus -> Graph (Node UnitId ElaboratedPlanPackage)
packagesBuildLocal :: PostBuildProjectStatus -> PackagesUpToDate
packagesBuildInplace :: PostBuildProjectStatus -> PackagesUpToDate
packagesAlreadyInStore :: PostBuildProjectStatus -> PackagesUpToDate
packagesDefinitelyUpToDate :: PackagesUpToDate
packagesProbablyUpToDate :: PackagesUpToDate
packagesOutOfDate :: PackagesUpToDate
packagesInvalidByChangedLibDeps :: PackagesUpToDate
packagesInvalidByFailedBuild :: PackagesUpToDate
packagesLibDepGraph :: Graph (Node UnitId ElaboratedPlanPackage)
packagesBuildLocal :: PackagesUpToDate
packagesBuildInplace :: PackagesUpToDate
packagesAlreadyInStore :: PackagesUpToDate
..} =
ElaboratedInstallPlan
-> PackagesUpToDate
-> BuildStatusMap
-> BuildOutcomes
-> PostBuildProjectStatus
postBuildProjectStatus
ElaboratedInstallPlan
elaboratedInstallPlan
PackagesUpToDate
previousUpToDate
BuildStatusMap
pkgsBuildStatus
BuildOutcomes
buildOutcomes
let currentUpToDate :: PackagesUpToDate
currentUpToDate = PackagesUpToDate
packagesProbablyUpToDate
DistDirLayout -> PackagesUpToDate -> IO ()
writePackagesUpToDateCacheFile DistDirLayout
distDirLayout PackagesUpToDate
currentUpToDate
Verbosity -> String -> IO ()
debugNoWrap Verbosity
verbosity (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$
String
"packages definitely up to date: "
String -> String -> String
forall a. [a] -> [a] -> [a]
++ PackagesUpToDate -> String
displayPackageIdSet
( PackagesUpToDate
packagesDefinitelyUpToDate
PackagesUpToDate -> PackagesUpToDate -> PackagesUpToDate
forall a. Ord a => Set a -> Set a -> Set a
`Set.intersection` PackagesUpToDate
packagesBuildInplace
)
Verbosity -> String -> IO ()
debugNoWrap Verbosity
verbosity (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$
String
"packages previously probably up to date: "
String -> String -> String
forall a. [a] -> [a] -> [a]
++ PackagesUpToDate -> String
displayPackageIdSet
( PackagesUpToDate
previousUpToDate
PackagesUpToDate -> PackagesUpToDate -> PackagesUpToDate
forall a. Ord a => Set a -> Set a -> Set a
`Set.intersection` PackagesUpToDate
packagesBuildInplace
)
Verbosity -> String -> IO ()
debugNoWrap Verbosity
verbosity (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$
String
"packages now probably up to date: "
String -> String -> String
forall a. [a] -> [a] -> [a]
++ PackagesUpToDate -> String
displayPackageIdSet
( PackagesUpToDate
packagesProbablyUpToDate
PackagesUpToDate -> PackagesUpToDate -> PackagesUpToDate
forall a. Ord a => Set a -> Set a -> Set a
`Set.intersection` PackagesUpToDate
packagesBuildInplace
)
Verbosity -> String -> IO ()
debugNoWrap Verbosity
verbosity (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$
String
"packages newly up to date: "
String -> String -> String
forall a. [a] -> [a] -> [a]
++ PackagesUpToDate -> String
displayPackageIdSet
( PackagesUpToDate
packagesDefinitelyUpToDate
PackagesUpToDate -> PackagesUpToDate -> PackagesUpToDate
forall a. Ord a => Set a -> Set a -> Set a
`Set.difference` PackagesUpToDate
previousUpToDate
PackagesUpToDate -> PackagesUpToDate -> PackagesUpToDate
forall a. Ord a => Set a -> Set a -> Set a
`Set.intersection` PackagesUpToDate
packagesBuildInplace
)
Verbosity -> String -> IO ()
debugNoWrap Verbosity
verbosity (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$
String
"packages out to date: "
String -> String -> String
forall a. [a] -> [a] -> [a]
++ PackagesUpToDate -> String
displayPackageIdSet
( PackagesUpToDate
packagesOutOfDate
PackagesUpToDate -> PackagesUpToDate -> PackagesUpToDate
forall a. Ord a => Set a -> Set a -> Set a
`Set.intersection` PackagesUpToDate
packagesBuildInplace
)
Verbosity -> String -> IO ()
debugNoWrap Verbosity
verbosity (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$
String
"packages invalid due to dep change: "
String -> String -> String
forall a. [a] -> [a] -> [a]
++ PackagesUpToDate -> String
displayPackageIdSet PackagesUpToDate
packagesInvalidByChangedLibDeps
Verbosity -> String -> IO ()
debugNoWrap Verbosity
verbosity (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$
String
"packages invalid due to build failure: "
String -> String -> String
forall a. [a] -> [a] -> [a]
++ PackagesUpToDate -> String
displayPackageIdSet PackagesUpToDate
packagesInvalidByFailedBuild
PostBuildProjectStatus -> IO PostBuildProjectStatus
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return PostBuildProjectStatus
currentBuildStatus
where
displayPackageIdSet :: PackagesUpToDate -> String
displayPackageIdSet = String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
", " ([String] -> String)
-> (PackagesUpToDate -> [String]) -> PackagesUpToDate -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (UnitId -> String) -> [UnitId] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map UnitId -> String
forall a. Pretty a => a -> String
prettyShow ([UnitId] -> [String])
-> (PackagesUpToDate -> [UnitId]) -> PackagesUpToDate -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PackagesUpToDate -> [UnitId]
forall a. Set a -> [a]
Set.toList
readPackagesUpToDateCacheFile :: DistDirLayout -> IO PackagesUpToDate
readPackagesUpToDateCacheFile :: DistDirLayout -> IO PackagesUpToDate
readPackagesUpToDateCacheFile DistDirLayout{String -> String
distProjectCacheFile :: DistDirLayout -> String -> String
distProjectCacheFile :: String -> String
distProjectCacheFile} =
PackagesUpToDate -> IO PackagesUpToDate -> IO PackagesUpToDate
forall a. a -> IO a -> IO a
handleDoesNotExist PackagesUpToDate
forall a. Set a
Set.empty (IO PackagesUpToDate -> IO PackagesUpToDate)
-> IO PackagesUpToDate -> IO PackagesUpToDate
forall a b. (a -> b) -> a -> b
$
IO (Either String PackagesUpToDate) -> IO PackagesUpToDate
forall {a} {a}. IO (Either a (Set a)) -> IO (Set a)
handleDecodeFailure (IO (Either String PackagesUpToDate) -> IO PackagesUpToDate)
-> IO (Either String PackagesUpToDate) -> IO PackagesUpToDate
forall a b. (a -> b) -> a -> b
$
String
-> IOMode
-> (Handle -> IO (Either String PackagesUpToDate))
-> IO (Either String PackagesUpToDate)
forall r. String -> IOMode -> (Handle -> IO r) -> IO r
withBinaryFile (String -> String
distProjectCacheFile String
"up-to-date") IOMode
ReadMode ((Handle -> IO (Either String PackagesUpToDate))
-> IO (Either String PackagesUpToDate))
-> (Handle -> IO (Either String PackagesUpToDate))
-> IO (Either String PackagesUpToDate)
forall a b. (a -> b) -> a -> b
$ \Handle
hnd ->
ByteString -> IO (Either String PackagesUpToDate)
forall a. Binary a => ByteString -> IO (Either String a)
Binary.decodeOrFailIO (ByteString -> IO (Either String PackagesUpToDate))
-> IO ByteString -> IO (Either String PackagesUpToDate)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Handle -> IO ByteString
BS.hGetContents Handle
hnd
where
handleDecodeFailure :: IO (Either a (Set a)) -> IO (Set a)
handleDecodeFailure = (Either a (Set a) -> Set a) -> IO (Either a (Set a)) -> IO (Set a)
forall a b. (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((a -> Set a) -> (Set a -> Set a) -> Either a (Set a) -> Set a
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (Set a -> a -> Set a
forall a b. a -> b -> a
const Set a
forall a. Set a
Set.empty) Set a -> Set a
forall a. a -> a
id)
writePackagesUpToDateCacheFile :: DistDirLayout -> PackagesUpToDate -> IO ()
writePackagesUpToDateCacheFile :: DistDirLayout -> PackagesUpToDate -> IO ()
writePackagesUpToDateCacheFile DistDirLayout{String -> String
distProjectCacheFile :: DistDirLayout -> String -> String
distProjectCacheFile :: String -> String
distProjectCacheFile} PackagesUpToDate
upToDate =
String -> ByteString -> IO ()
writeFileAtomic (String -> String
distProjectCacheFile String
"up-to-date") (ByteString -> IO ()) -> ByteString -> IO ()
forall a b. (a -> b) -> a -> b
$
PackagesUpToDate -> ByteString
forall a. Binary a => a -> ByteString
Binary.encode PackagesUpToDate
upToDate
createPackageEnvironment
:: Verbosity
-> FilePath
-> ElaboratedInstallPlan
-> ElaboratedSharedConfig
-> PostBuildProjectStatus
-> IO [(String, Maybe String)]
createPackageEnvironment :: Verbosity
-> String
-> ElaboratedInstallPlan
-> ElaboratedSharedConfig
-> PostBuildProjectStatus
-> IO [(String, Maybe String)]
createPackageEnvironment
Verbosity
verbosity
String
path
ElaboratedInstallPlan
elaboratedPlan
ElaboratedSharedConfig
elaboratedShared
PostBuildProjectStatus
buildStatus
| Compiler -> CompilerFlavor
compilerFlavor (ElaboratedSharedConfig -> Compiler
pkgConfigCompiler ElaboratedSharedConfig
elaboratedShared) CompilerFlavor -> CompilerFlavor -> Bool
forall a. Eq a => a -> a -> Bool
== CompilerFlavor
GHC =
do
Maybe String
envFileM <-
String
-> ElaboratedInstallPlan
-> ElaboratedSharedConfig
-> PostBuildProjectStatus
-> IO (Maybe String)
writePlanGhcEnvironment
String
path
ElaboratedInstallPlan
elaboratedPlan
ElaboratedSharedConfig
elaboratedShared
PostBuildProjectStatus
buildStatus
case Maybe String
envFileM of
Just String
envFile -> [(String, Maybe String)] -> IO [(String, Maybe String)]
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return [(String
"GHC_ENVIRONMENT", String -> Maybe String
forall a. a -> Maybe a
Just String
envFile)]
Maybe String
Nothing -> do
Verbosity -> String -> IO ()
warn Verbosity
verbosity String
"the configured version of GHC does not support reading package lists from the environment; commands that need the current project's package database are likely to fail"
[(String, Maybe String)] -> IO [(String, Maybe String)]
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return []
| Bool
otherwise =
do
Verbosity -> String -> IO ()
warn Verbosity
verbosity String
"package environment configuration is not supported for the currently configured compiler; commands that need the current project's package database are likely to fail"
[(String, Maybe String)] -> IO [(String, Maybe String)]
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return []
writePlanGhcEnvironment
:: FilePath
-> ElaboratedInstallPlan
-> ElaboratedSharedConfig
-> PostBuildProjectStatus
-> IO (Maybe FilePath)
writePlanGhcEnvironment :: String
-> ElaboratedInstallPlan
-> ElaboratedSharedConfig
-> PostBuildProjectStatus
-> IO (Maybe String)
writePlanGhcEnvironment
String
path
ElaboratedInstallPlan
elaboratedInstallPlan
ElaboratedSharedConfig
{ pkgConfigCompiler :: ElaboratedSharedConfig -> Compiler
pkgConfigCompiler = Compiler
compiler
, pkgConfigPlatform :: ElaboratedSharedConfig -> Platform
pkgConfigPlatform = Platform
platform
}
PostBuildProjectStatus
postBuildStatus
| Compiler -> CompilerFlavor
compilerFlavor Compiler
compiler CompilerFlavor -> CompilerFlavor -> Bool
forall a. Eq a => a -> a -> Bool
== CompilerFlavor
GHC
, GhcImplInfo -> Bool
supportsPkgEnvFiles (Compiler -> GhcImplInfo
getImplInfo Compiler
compiler) =
(String -> Maybe String) -> IO String -> IO (Maybe String)
forall a b. (a -> b) -> IO a -> IO b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap String -> Maybe String
forall a. a -> Maybe a
Just (IO String -> IO (Maybe String)) -> IO String -> IO (Maybe String)
forall a b. (a -> b) -> a -> b
$
String
-> Platform
-> Version
-> [GhcEnvironmentFileEntry String]
-> IO String
writeGhcEnvironmentFile
String
path
Platform
platform
(Compiler -> Version
compilerVersion Compiler
compiler)
( String
-> ElaboratedInstallPlan
-> PostBuildProjectStatus
-> [GhcEnvironmentFileEntry String]
renderGhcEnvironmentFile
String
path
ElaboratedInstallPlan
elaboratedInstallPlan
PostBuildProjectStatus
postBuildStatus
)
writePlanGhcEnvironment String
_ ElaboratedInstallPlan
_ ElaboratedSharedConfig
_ PostBuildProjectStatus
_ = Maybe String -> IO (Maybe String)
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe String
forall a. Maybe a
Nothing
renderGhcEnvironmentFile
:: FilePath
-> ElaboratedInstallPlan
-> PostBuildProjectStatus
-> [GhcEnvironmentFileEntry FilePath]
renderGhcEnvironmentFile :: String
-> ElaboratedInstallPlan
-> PostBuildProjectStatus
-> [GhcEnvironmentFileEntry String]
renderGhcEnvironmentFile
String
projectRootDir
ElaboratedInstallPlan
elaboratedInstallPlan
PostBuildProjectStatus
postBuildStatus =
GhcEnvironmentFileEntry String
forall {fp}. GhcEnvironmentFileEntry fp
headerComment
GhcEnvironmentFileEntry String
-> [GhcEnvironmentFileEntry String]
-> [GhcEnvironmentFileEntry String]
forall a. a -> [a] -> [a]
: PackageDBStackCWD -> [UnitId] -> [GhcEnvironmentFileEntry String]
forall fp.
PackageDBStackX fp -> [UnitId] -> [GhcEnvironmentFileEntry fp]
simpleGhcEnvironmentFile PackageDBStackCWD
packageDBs [UnitId]
unitIds
where
headerComment :: GhcEnvironmentFileEntry fp
headerComment =
String -> GhcEnvironmentFileEntry fp
forall fp. String -> GhcEnvironmentFileEntry fp
GhcEnvFileComment (String -> GhcEnvironmentFileEntry fp)
-> String -> GhcEnvironmentFileEntry fp
forall a b. (a -> b) -> a -> b
$
String
"This is a GHC environment file written by cabal. This means you can\n"
String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"run ghc or ghci and get the environment of the project as a whole.\n"
String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"But you still need to use cabal repl $target to get the environment\n"
String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"of specific components (libs, exes, tests etc) because each one can\n"
String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"have its own source dirs, cpp flags etc.\n\n"
unitIds :: [UnitId]
unitIds = PostBuildProjectStatus -> [UnitId]
selectGhcEnvironmentFileLibraries PostBuildProjectStatus
postBuildStatus
packageDBs :: PackageDBStackCWD
packageDBs =
String -> PackageDBStackCWD -> PackageDBStackCWD
relativePackageDBPaths String
projectRootDir (PackageDBStackCWD -> PackageDBStackCWD)
-> PackageDBStackCWD -> PackageDBStackCWD
forall a b. (a -> b) -> a -> b
$
ElaboratedInstallPlan -> PackageDBStackCWD
selectGhcEnvironmentFilePackageDbs ElaboratedInstallPlan
elaboratedInstallPlan
argsEquivalentOfGhcEnvironmentFile
:: Compiler
-> DistDirLayout
-> ElaboratedInstallPlan
-> PostBuildProjectStatus
-> [String]
argsEquivalentOfGhcEnvironmentFile :: Compiler
-> DistDirLayout
-> ElaboratedInstallPlan
-> PostBuildProjectStatus
-> [String]
argsEquivalentOfGhcEnvironmentFile Compiler
compiler =
case Compiler -> CompilerId
compilerId Compiler
compiler of
CompilerId CompilerFlavor
GHC Version
_ -> DistDirLayout
-> ElaboratedInstallPlan -> PostBuildProjectStatus -> [String]
argsEquivalentOfGhcEnvironmentFileGhc
CompilerId CompilerFlavor
GHCJS Version
_ -> DistDirLayout
-> ElaboratedInstallPlan -> PostBuildProjectStatus -> [String]
argsEquivalentOfGhcEnvironmentFileGhc
CompilerId CompilerFlavor
_ Version
_ -> String
-> DistDirLayout
-> ElaboratedInstallPlan
-> PostBuildProjectStatus
-> [String]
forall a. HasCallStack => String -> a
error String
"Only GHC and GHCJS are supported"
argsEquivalentOfGhcEnvironmentFileGhc
:: DistDirLayout
-> ElaboratedInstallPlan
-> PostBuildProjectStatus
-> [String]
argsEquivalentOfGhcEnvironmentFileGhc :: DistDirLayout
-> ElaboratedInstallPlan -> PostBuildProjectStatus -> [String]
argsEquivalentOfGhcEnvironmentFileGhc
DistDirLayout
distDirLayout
ElaboratedInstallPlan
elaboratedInstallPlan
PostBuildProjectStatus
postBuildStatus =
[String]
clearPackageDbStackFlag
[String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ PackageDBStackCWD -> [String]
packageDbArgsDb PackageDBStackCWD
packageDBs
[String] -> [String] -> [String]
forall a. [a] -> [a] -> [a]
++ (UnitId -> [String]) -> [UnitId] -> [String]
forall m a. Monoid m => (a -> m) -> [a] -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap UnitId -> [String]
forall {a}. Pretty a => a -> [String]
packageIdFlag [UnitId]
packageIds
where
projectRootDir :: String
projectRootDir = DistDirLayout -> String
distProjectRootDirectory DistDirLayout
distDirLayout
packageIds :: [UnitId]
packageIds = PostBuildProjectStatus -> [UnitId]
selectGhcEnvironmentFileLibraries PostBuildProjectStatus
postBuildStatus
packageDBs :: PackageDBStackCWD
packageDBs =
String -> PackageDBStackCWD -> PackageDBStackCWD
relativePackageDBPaths String
projectRootDir (PackageDBStackCWD -> PackageDBStackCWD)
-> PackageDBStackCWD -> PackageDBStackCWD
forall a b. (a -> b) -> a -> b
$
ElaboratedInstallPlan -> PackageDBStackCWD
selectGhcEnvironmentFilePackageDbs ElaboratedInstallPlan
elaboratedInstallPlan
clearPackageDbStackFlag :: [String]
clearPackageDbStackFlag = [String
"-clear-package-db", String
"-global-package-db"]
packageIdFlag :: a -> [String]
packageIdFlag a
uid = [String
"-package-id", a -> String
forall a. Pretty a => a -> String
prettyShow a
uid]
selectGhcEnvironmentFileLibraries :: PostBuildProjectStatus -> [UnitId]
selectGhcEnvironmentFileLibraries :: PostBuildProjectStatus -> [UnitId]
selectGhcEnvironmentFileLibraries PostBuildProjectStatus{PackagesUpToDate
Graph (Node UnitId ElaboratedPlanPackage)
packagesDefinitelyUpToDate :: PostBuildProjectStatus -> PackagesUpToDate
packagesProbablyUpToDate :: PostBuildProjectStatus -> PackagesUpToDate
packagesOutOfDate :: PostBuildProjectStatus -> PackagesUpToDate
packagesInvalidByChangedLibDeps :: PostBuildProjectStatus -> PackagesUpToDate
packagesInvalidByFailedBuild :: PostBuildProjectStatus -> PackagesUpToDate
packagesLibDepGraph :: PostBuildProjectStatus -> Graph (Node UnitId ElaboratedPlanPackage)
packagesBuildLocal :: PostBuildProjectStatus -> PackagesUpToDate
packagesBuildInplace :: PostBuildProjectStatus -> PackagesUpToDate
packagesAlreadyInStore :: PostBuildProjectStatus -> PackagesUpToDate
packagesDefinitelyUpToDate :: PackagesUpToDate
packagesProbablyUpToDate :: PackagesUpToDate
packagesOutOfDate :: PackagesUpToDate
packagesInvalidByChangedLibDeps :: PackagesUpToDate
packagesInvalidByFailedBuild :: PackagesUpToDate
packagesLibDepGraph :: Graph (Node UnitId ElaboratedPlanPackage)
packagesBuildLocal :: PackagesUpToDate
packagesBuildInplace :: PackagesUpToDate
packagesAlreadyInStore :: PackagesUpToDate
..} =
case Graph (Node UnitId ElaboratedPlanPackage)
-> [Key (Node UnitId ElaboratedPlanPackage)]
-> Maybe [Node UnitId ElaboratedPlanPackage]
forall a. Graph a -> [Key a] -> Maybe [a]
Graph.closure Graph (Node UnitId ElaboratedPlanPackage)
packagesLibDepGraph (PackagesUpToDate -> [UnitId]
forall a. Set a -> [a]
Set.toList PackagesUpToDate
packagesBuildLocal) of
Maybe [Node UnitId ElaboratedPlanPackage]
Nothing -> String -> [UnitId]
forall a. HasCallStack => String -> a
error String
"renderGhcEnvironmentFile: broken dep closure"
Just [Node UnitId ElaboratedPlanPackage]
nodes ->
[ UnitId
pkgid | Graph.N ElaboratedPlanPackage
pkg UnitId
pkgid [UnitId]
_ <- [Node UnitId ElaboratedPlanPackage]
nodes, ElaboratedPlanPackage -> Bool
forall {ipkg}.
GenericPlanPackage ipkg ElaboratedConfiguredPackage -> Bool
hasUpToDateLib ElaboratedPlanPackage
pkg
]
where
hasUpToDateLib :: GenericPlanPackage ipkg ElaboratedConfiguredPackage -> Bool
hasUpToDateLib GenericPlanPackage ipkg ElaboratedConfiguredPackage
planpkg = case GenericPlanPackage ipkg ElaboratedConfiguredPackage
planpkg of
InstallPlan.PreExisting ipkg
_ -> Bool
True
InstallPlan.Installed ElaboratedConfiguredPackage
pkg -> ElaboratedConfiguredPackage -> Bool
elabRequiresRegistration ElaboratedConfiguredPackage
pkg
InstallPlan.Configured ElaboratedConfiguredPackage
pkg ->
ElaboratedConfiguredPackage -> Bool
elabRequiresRegistration ElaboratedConfiguredPackage
pkg
Bool -> Bool -> Bool
&& ElaboratedConfiguredPackage -> UnitId
forall pkg. HasUnitId pkg => pkg -> UnitId
installedUnitId ElaboratedConfiguredPackage
pkg UnitId -> PackagesUpToDate -> Bool
forall a. Ord a => a -> Set a -> Bool
`Set.member` PackagesUpToDate
packagesProbablyUpToDate
selectGhcEnvironmentFilePackageDbs :: ElaboratedInstallPlan -> PackageDBStackCWD
selectGhcEnvironmentFilePackageDbs :: ElaboratedInstallPlan -> PackageDBStackCWD
selectGhcEnvironmentFilePackageDbs ElaboratedInstallPlan
elaboratedInstallPlan =
case ([ElaboratedConfiguredPackage]
inplacePackages, [ElaboratedConfiguredPackage]
sourcePackages) of
([], [ElaboratedConfiguredPackage]
pkgs) -> [ElaboratedConfiguredPackage] -> PackageDBStackCWD
checkSamePackageDBs [ElaboratedConfiguredPackage]
pkgs
([ElaboratedConfiguredPackage]
pkgs, [ElaboratedConfiguredPackage]
_) -> [ElaboratedConfiguredPackage] -> PackageDBStackCWD
checkSamePackageDBs [ElaboratedConfiguredPackage]
pkgs
where
checkSamePackageDBs :: [ElaboratedConfiguredPackage] -> PackageDBStackCWD
checkSamePackageDBs :: [ElaboratedConfiguredPackage] -> PackageDBStackCWD
checkSamePackageDBs [ElaboratedConfiguredPackage]
pkgs =
case [PackageDBStackCWD] -> [PackageDBStackCWD]
forall a. Ord a => [a] -> [a]
ordNub ((ElaboratedConfiguredPackage -> PackageDBStackCWD)
-> [ElaboratedConfiguredPackage] -> [PackageDBStackCWD]
forall a b. (a -> b) -> [a] -> [b]
map ElaboratedConfiguredPackage -> PackageDBStackCWD
elabBuildPackageDBStack [ElaboratedConfiguredPackage]
pkgs) of
[PackageDBStackCWD
packageDbs] -> PackageDBStackCWD
packageDbs
[] -> []
[PackageDBStackCWD]
_ ->
String -> PackageDBStackCWD
forall a. HasCallStack => String -> a
error (String -> PackageDBStackCWD) -> String -> PackageDBStackCWD
forall a b. (a -> b) -> a -> b
$
String
"renderGhcEnvironmentFile: packages with "
String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"different package db stacks"
inplacePackages :: [ElaboratedConfiguredPackage]
inplacePackages :: [ElaboratedConfiguredPackage]
inplacePackages =
[ ElaboratedConfiguredPackage
srcpkg
| ElaboratedConfiguredPackage
srcpkg <- [ElaboratedConfiguredPackage]
sourcePackages
, BuildStyle -> Bool
isInplaceBuildStyle (ElaboratedConfiguredPackage -> BuildStyle
elabBuildStyle ElaboratedConfiguredPackage
srcpkg)
]
sourcePackages :: [ElaboratedConfiguredPackage]
sourcePackages :: [ElaboratedConfiguredPackage]
sourcePackages =
[ ElaboratedConfiguredPackage
srcpkg
| ElaboratedPlanPackage
pkg <- ElaboratedInstallPlan -> [ElaboratedPlanPackage]
forall ipkg srcpkg.
GenericInstallPlan ipkg srcpkg -> [GenericPlanPackage ipkg srcpkg]
InstallPlan.toList ElaboratedInstallPlan
elaboratedInstallPlan
, ElaboratedConfiguredPackage
srcpkg <- Maybe ElaboratedConfiguredPackage -> [ElaboratedConfiguredPackage]
forall a. Maybe a -> [a]
maybeToList (Maybe ElaboratedConfiguredPackage
-> [ElaboratedConfiguredPackage])
-> Maybe ElaboratedConfiguredPackage
-> [ElaboratedConfiguredPackage]
forall a b. (a -> b) -> a -> b
$ case ElaboratedPlanPackage
pkg of
InstallPlan.Configured ElaboratedConfiguredPackage
srcpkg -> ElaboratedConfiguredPackage -> Maybe ElaboratedConfiguredPackage
forall a. a -> Maybe a
Just ElaboratedConfiguredPackage
srcpkg
InstallPlan.Installed ElaboratedConfiguredPackage
srcpkg -> ElaboratedConfiguredPackage -> Maybe ElaboratedConfiguredPackage
forall a. a -> Maybe a
Just ElaboratedConfiguredPackage
srcpkg
InstallPlan.PreExisting InstalledPackageInfo
_ -> Maybe ElaboratedConfiguredPackage
forall a. Maybe a
Nothing
]
relativePackageDBPaths :: FilePath -> PackageDBStackCWD -> PackageDBStackCWD
relativePackageDBPaths :: String -> PackageDBStackCWD -> PackageDBStackCWD
relativePackageDBPaths String
relroot = (PackageDBX String -> PackageDBX String)
-> PackageDBStackCWD -> PackageDBStackCWD
forall a b. (a -> b) -> [a] -> [b]
map (String -> PackageDBX String -> PackageDBX String
relativePackageDBPath String
relroot)
relativePackageDBPath :: FilePath -> PackageDBCWD -> PackageDBCWD
relativePackageDBPath :: String -> PackageDBX String -> PackageDBX String
relativePackageDBPath String
relroot PackageDBX String
pkgdb =
case PackageDBX String
pkgdb of
PackageDBX String
GlobalPackageDB -> PackageDBX String
forall fp. PackageDBX fp
GlobalPackageDB
PackageDBX String
UserPackageDB -> PackageDBX String
forall fp. PackageDBX fp
UserPackageDB
SpecificPackageDB String
path -> String -> PackageDBX String
forall fp. fp -> PackageDBX fp
SpecificPackageDB String
relpath
where
relpath :: String
relpath = String -> String -> String
makeRelative (String -> String
normalise String
relroot) String
path