1 {-# OPTIONS_GHC -fno-warn-incomplete-uni-patterns #-}
3 -----------------------------------------------------------------------------
5 -----------------------------------------------------------------------------
8 -- Module : Distribution.Client.Reporting
9 -- Copyright : (c) David Waern 2008
12 -- Maintainer : david.waern@gmail.com
13 -- Stability : experimental
14 -- Portability : portable
16 -- Anonymous build report data structure, printing and parsing
17 module Distribution
.Client
.BuildReports
.Storage
18 ( -- * Storing and retrieving build reports
23 -- * 'InstallPlan' support
28 import Distribution
.Client
.Compat
.Prelude
31 import Distribution
.Client
.BuildReports
.Anonymous
(BuildReport
, newBuildReport
, showBuildReport
)
32 import qualified Distribution
.Client
.BuildReports
.Anonymous
as BuildReport
34 import Distribution
.Client
.InstallPlan
37 import qualified Distribution
.Client
.InstallPlan
as InstallPlan
38 import Distribution
.Client
.Types
40 import qualified Distribution
.Solver
.Types
.ComponentDeps
as CD
41 import Distribution
.Solver
.Types
.SourcePackage
43 import Distribution
.Compiler
47 import Distribution
.Package
51 import Distribution
.PackageDescription
54 import Distribution
.Simple
.InstallDirs
57 , initialPathTemplateEnv
60 import Distribution
.Simple
.Utils
63 import Distribution
.System
67 import qualified Data
.List
as L
68 import Data
.List
.NonEmpty
71 import System
.Directory
72 ( createDirectoryIfMissing
74 import System
.FilePath
79 storeAnonymous
:: [(BuildReport
, Maybe Repo
)] -> IO ()
80 storeAnonymous reports
=
82 [ appendFile file
(concatMap format reports
')
83 |
(repo
, reports
') <- separate reports
84 , let file
= repoLocalDir repo
</> "build-reports.log"
87 -- TODO: make this concurrency safe, either lock the report file or make sure
88 -- the writes for each report are atomic (under 4k and flush at boundaries)
90 format r
= '\n' : showBuildReport r
++ "\n"
92 :: [(BuildReport
, Maybe Repo
)]
93 -> [(Repo
, [BuildReport
])]
95 map (\rs
@((_
, repo
, _
) : _
) -> (repo
, [r |
(r
, _
, _
) <- rs
]))
96 . map (concatMap toList
)
97 . L
.groupBy (equating
(repoName
' . head))
98 . sortBy (comparing
(repoName
' . head))
99 . groupBy (equating repoName
')
102 repoName
' (_
, _
, rrepo
) = remoteRepoName rrepo
105 :: [(BuildReport
, Maybe Repo
)]
106 -> [(BuildReport
, Repo
, RemoteRepo
)]
108 [ (report
, repo
, remoteRepo
)
109 |
(report
, Just repo
) <- rs
110 , Just remoteRepo
<- [maybeRepoRemote repo
]
116 -> [(BuildReport
, Maybe Repo
)]
119 storeLocal cinfo templates reports platform
=
122 createDirectoryIfMissing
True (takeDirectory file
)
123 appendFile file output
124 |
-- TODO: make this concurrency safe, either lock the report file or make
125 -- sure the writes for each report are atomic
128 [ (reportFileName template report
, report
)
129 | template
<- templates
130 , (report
, _repo
) <- reports
132 , let output
= concatMap format reports
'
135 format r
= '\n' : showBuildReport r
++ "\n"
137 reportFileName template report
=
138 fromPathTemplate
(substPathTemplate env template
)
141 initialPathTemplateEnv
142 (BuildReport
.package report
)
143 -- TODO: In principle, we can support $pkgkey, but only
144 -- if the configure step succeeds. So add a Maybe field
145 -- to the build report, and either use that or make up
146 -- a fake identifier if it's not available.
147 (error "storeLocal: package key not available")
152 map (\grp
@((filename
, _
) : _
) -> (filename
, map snd grp
))
153 . L
.groupBy (equating
fst)
154 . sortBy (comparing
fst)
156 -- ------------------------------------------------------------
158 -- * InstallPlan support
160 -- ------------------------------------------------------------
167 -> [(BuildReport
, Maybe Repo
)]
168 fromInstallPlan platform comp plan buildOutcomes
=
175 (InstallPlan
.lookupBuildOutcome pkg buildOutcomes
)
183 -> InstallPlan
.PlanPackage
184 -> Maybe BuildOutcome
185 -> Maybe (BuildReport
, Maybe Repo
)
189 (InstallPlan
.Configured
(ConfiguredPackage _ srcPkg flags _ deps
))
198 (map packageId
(CD
.nonSetupDeps deps
))
203 extractRepo
(SourcePackage
{srcpkgSource
= RepoTarballPackage repo _ _
}) =
205 extractRepo _
= Nothing
206 fromPlanPackage _ _ _ _
= Nothing
213 -> [(BuildReport
, Maybe Repo
)]
214 fromPlanningFailure
(Platform arch os
) comp pkgids flags
=
215 [ (newBuildReport os arch comp pkgid flags
[] (Left PlanningFailed
), Nothing
)