From 5bf9c473b84fbc4441b27f6c8e2cf4b2906a10f3 Mon Sep 17 00:00:00 2001
From: Duncan Coutts <duncan@haskell.org>
Date: Thu, 7 Aug 2008 18:39:45 +0000
Subject: [PATCH] Rearrange the BuildReport code

---
 .../Anonymous.hs}                             | 152 +++------
 .../Client/BuildReports/Storage.hs            | 114 +++++++
 cabal-install/Distribution/Client/Install.hs  |  12 +-
 cabal-install/Distribution/Client/Logging.hs  | 292 ------------------
 4 files changed, 164 insertions(+), 406 deletions(-)
 rename cabal-install/Distribution/Client/{Reporting.hs => BuildReports/Anonymous.hs} (64%)
 create mode 100644 cabal-install/Distribution/Client/BuildReports/Storage.hs
 delete mode 100644 cabal-install/Distribution/Client/Logging.hs

diff --git a/cabal-install/Distribution/Client/Reporting.hs b/cabal-install/Distribution/Client/BuildReports/Anonymous.hs
similarity index 64%
rename from cabal-install/Distribution/Client/Reporting.hs
rename to cabal-install/Distribution/Client/BuildReports/Anonymous.hs
index 605b5b7372..7b27a0a22e 100644
--- a/cabal-install/Distribution/Client/Reporting.hs
+++ b/cabal-install/Distribution/Client/BuildReports/Anonymous.hs
@@ -8,38 +8,29 @@
 -- Stability   :  experimental
 -- Portability :  portable
 --
--- Report data structure
+-- Anonymous build report data structure, printing and parsing
 --
 -----------------------------------------------------------------------------
-module Distribution.Client.Reporting (
+module Distribution.Client.BuildReports.Anonymous (
     BuildReport(..),
     InstallOutcome(..),
     Outcome(..),
 
     -- * Constructing and writing reports
-    buildReport,
-    writeBuildReports,
+    new,
 
     -- * parsing and pretty printing
-    parseBuildReport,
-    parseBuildReports,
-    showBuildReport,
-
-    -- * 'InstallPlan' variants
-    planPackageBuildReport,
-    installPlanBuildReports,
-    writeInstallPlanBuildReports
+    parse,
+    parseList,
+    show,
+    showList,
   ) where
 
 import Distribution.Client.Types
-         ( ConfiguredPackage(..), AvailablePackage(..), BuildResult
-         , AvailablePackageSource(..), Repo(..), RemoteRepo(..) )
+         ( ConfiguredPackage(..), BuildResult )
 import qualified Distribution.Client.Types as BR
          ( BuildResult, BuildFailure(..), BuildSuccess(..)
          , DocsResult(..), TestsResult(..) )
-import qualified Distribution.Client.InstallPlan as InstallPlan
-import Distribution.Client.InstallPlan
-         ( InstallPlan, PlanPackage )
 import Distribution.Client.ParseUtils
          ( parseFields )
 import qualified Paths_cabal_install (version)
@@ -54,25 +45,24 @@ import Distribution.System
          ( OS, Arch )
 import Distribution.Compiler
          ( CompilerId )
-import Distribution.Text
+import qualified Distribution.Text as Text
          ( Text(disp, parse) )
 import Distribution.ParseUtils
-         ( FieldDescr(..), ParseResult(..), simpleField, listField, ppFields )
+         ( FieldDescr(..), ParseResult(..)
+         , simpleField, listField, ppFields, locatedErrorMsg )
 import qualified Distribution.Compat.ReadP as Parse
          ( ReadP, pfail, munch1, char, option, skipSpaces )
-import Text.PrettyPrint.HughesPJ as Disp
-         ( Doc, render, char, text, (<+>), (<>) )
-import Distribution.Simple.Utils
-         ( comparing, equating )
+import qualified Text.PrettyPrint.HughesPJ as Disp
+         ( Doc, render, char, text )
+import Text.PrettyPrint.HughesPJ
+         ( (<+>), (<>) )
 
 import Data.List
-         ( unfoldr, groupBy, sortBy )
-import Data.Maybe
-         ( catMaybes )
+         ( unfoldr )
 import Data.Char as Char
          ( isAlpha, isAlphaNum )
-import System.FilePath
-         ( (</>) )
+
+import Prelude hiding (show)
 
 data BuildReport
    = BuildReport {
@@ -123,35 +113,10 @@ data InstallOutcome
 
 data Outcome = NotTried | Failed | Ok
 
-writeBuildReports :: [(BuildReport, Repo)] -> IO ()
-writeBuildReports reports = sequence_
-  [ appendFile file (concatMap format reports')
-  | (repo, reports') <- separate reports
-  , let file = repoLocalDir repo </> "build-reports.log" ]
-  --TODO: make this concurrency safe, either lock the report file or make sure
-  -- the writes for each report are atomic (under 4k and flush at boundaries)
-
-  where
-    format r = '\n' : showBuildReport r ++ "\n"
-    separate :: [(BuildReport, Repo)]
-             -> [(Repo, [BuildReport])]
-    separate = map (\rs@((_,repo,_):_) -> (repo, [ r | (r,_,_) <- rs ]))
-             . map concat
-             . groupBy (equating (repoName . head))
-             . sortBy (comparing (repoName . head))
-             . groupBy (equating repoName)
-             . onlyRemote
-    repoName (_,_,rrepo) = remoteRepoName rrepo
-
-    onlyRemote :: [(BuildReport, Repo)] -> [(BuildReport, Repo, RemoteRepo)]
-    onlyRemote rs =
-      [ (report, repo, remoteRepo)
-      | (report, repo@Repo { repoKind = Left remoteRepo }) <- rs ]
-
-buildReport :: OS -> Arch -> CompilerId -- -> Version
-            -> ConfiguredPackage -> BR.BuildResult
-            -> BuildReport
-buildReport os' arch' comp (ConfiguredPackage pkg flags deps) result =
+new :: OS -> Arch -> CompilerId -- -> Version
+    -> ConfiguredPackage -> BR.BuildResult
+    -> BuildReport
+new os' arch' comp (ConfiguredPackage pkg flags deps) result =
   BuildReport {
     package               = packageId pkg,
     os                    = os',
@@ -212,12 +177,14 @@ initialBuildReport = BuildReport {
 -- -----------------------------------------------------------------------------
 -- Parsing
 
-parseBuildReport :: String -> ParseResult BuildReport
-parseBuildReport = parseFields fieldDescrs initialBuildReport
+parse :: String -> Either String BuildReport
+parse s = case parseFields fieldDescrs initialBuildReport s of
+  ParseFailed perror -> Left  msg where (_, msg) = locatedErrorMsg perror
+  ParseOk   _ report -> Right report
 
-parseBuildReports :: String -> [BuildReport]
-parseBuildReports str =
-  [ report | ParseOk [] report <- map parseBuildReport (split str) ]
+parseList :: String -> [BuildReport]
+parseList str =
+  [ report | Right report <- map parse (split str) ]
 
   where
     split :: String -> [String]
@@ -229,33 +196,33 @@ parseBuildReports str =
 -- -----------------------------------------------------------------------------
 -- Pretty-printing
 
-showBuildReport :: BuildReport -> String
-showBuildReport br = Disp.render (ppFields br fieldDescrs)
+show :: BuildReport -> String
+show br = Disp.render (ppFields br fieldDescrs)
 
 -- -----------------------------------------------------------------------------
 -- Description of the fields, for parsing/printing
 
 fieldDescrs :: [FieldDescr BuildReport]
 fieldDescrs =
- [ simpleField "package"         disp           parse
+ [ simpleField "package"         Text.disp      Text.parse
                                  package        (\v r -> r { package = v })
- , simpleField "os"              disp           parse
+ , simpleField "os"              Text.disp      Text.parse
                                  os             (\v r -> r { os = v })
- , simpleField "arch"            disp           parse
+ , simpleField "arch"            Text.disp      Text.parse
                                  arch           (\v r -> r { arch = v })
- , simpleField "compiler"        disp           parse
+ , simpleField "compiler"        Text.disp      Text.parse
                                  compiler       (\v r -> r { compiler = v })
- , simpleField "client"          disp           parse
+ , simpleField "client"          Text.disp      Text.parse
                                  client         (\v r -> r { client = v })
  , listField   "flags"           dispFlag       parseFlag
                                  flagAssignment (\v r -> r { flagAssignment = v })
- , listField   "dependencies"    disp           parse
+ , listField   "dependencies"    Text.disp      Text.parse
                                  dependencies   (\v r -> r { dependencies = v })
- , simpleField "install-outcome" disp           parse
+ , simpleField "install-outcome" Text.disp      Text.parse
                                  installOutcome (\v r -> r { installOutcome = v })
- , simpleField "docs-outcome"    disp           parse
+ , simpleField "docs-outcome"    Text.disp      Text.parse
                                  docsOutcome    (\v r -> r { docsOutcome = v })
- , simpleField "tests-outcome"   disp           parse
+ , simpleField "tests-outcome"   Text.disp      Text.parse
                                  testsOutcome   (\v r -> r { testsOutcome = v })
  ]
 
@@ -269,8 +236,8 @@ parseFlag = do
   name  <- Parse.munch1 (\c -> Char.isAlphaNum c || c == '_' || c == '-')
   return (FlagName name, value)
 
-instance Text InstallOutcome where
-  disp (DependencyFailed pkgid) = Disp.text "DependencyFailed" <+> disp pkgid
+instance Text.Text InstallOutcome where
+  disp (DependencyFailed pkgid) = Disp.text "DependencyFailed" <+> Text.disp pkgid
   disp DownloadFailed  = Disp.text "DownloadFailed"
   disp UnpackFailed    = Disp.text "UnpackFailed"
   disp SetupFailed     = Disp.text "SetupFailed"
@@ -283,7 +250,7 @@ instance Text InstallOutcome where
     name <- Parse.munch1 Char.isAlphaNum
     case name of
       "DependencyFailed" -> do Parse.skipSpaces
-                               pkgid <- parse
+                               pkgid <- Text.parse
                                return (DependencyFailed pkgid)
       "DownloadFailed"   -> return DownloadFailed
       "UnpackFailed"     -> return UnpackFailed
@@ -294,7 +261,7 @@ instance Text InstallOutcome where
       "InstallOk"        -> return InstallOk
       _                  -> Parse.pfail
 
-instance Text Outcome where
+instance Text.Text Outcome where
   disp NotTried = Disp.text "NotTried"
   disp Failed   = Disp.text "Failed"
   disp Ok       = Disp.text "Ok"
@@ -305,34 +272,3 @@ instance Text Outcome where
       "Failed"   -> return Failed
       "Ok"       -> return Ok
       _          -> Parse.pfail
-
--- ------------------------------------------------------------
--- * InstallPlan support
--- ------------------------------------------------------------
-
-writeInstallPlanBuildReports :: InstallPlan -> IO ()
-writeInstallPlanBuildReports = writeBuildReports . installPlanBuildReports
-
-installPlanBuildReports :: InstallPlan -> [(BuildReport, Repo)]
-installPlanBuildReports plan = catMaybes
-                             . map (planPackageBuildReport os' arch' comp)
-                             . InstallPlan.toList
-                             $ plan
-  where os'   = InstallPlan.planOS plan
-        arch' = InstallPlan.planArch plan
-        comp  = InstallPlan.planCompiler plan
-
-planPackageBuildReport :: OS -> Arch -> CompilerId
-                       -> InstallPlan.PlanPackage
-                       -> Maybe (BuildReport, Repo)
-planPackageBuildReport os' arch' comp planPackage = case planPackage of
-
-  InstallPlan.Installed pkg@(ConfiguredPackage (AvailablePackage {
-                          packageSource = RepoTarballPackage repo }) _ _) result
-    -> Just $ (buildReport os' arch' comp pkg (Right result), repo)
-
-  InstallPlan.Failed pkg@(ConfiguredPackage (AvailablePackage {
-                       packageSource = RepoTarballPackage repo }) _ _) result
-    -> Just $ (buildReport os' arch' comp pkg (Left result), repo)
-
-  _ -> Nothing
diff --git a/cabal-install/Distribution/Client/BuildReports/Storage.hs b/cabal-install/Distribution/Client/BuildReports/Storage.hs
new file mode 100644
index 0000000000..c42f15f668
--- /dev/null
+++ b/cabal-install/Distribution/Client/BuildReports/Storage.hs
@@ -0,0 +1,114 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  Distribution.Client.Reporting
+-- Copyright   :  (c) David Waern 2008
+-- License     :  BSD-like
+--
+-- Maintainer  :  david.waern@gmail.com
+-- Stability   :  experimental
+-- Portability :  portable
+--
+-- Anonymous build report data structure, printing and parsing
+--
+-----------------------------------------------------------------------------
+module Distribution.Client.BuildReports.Storage (
+
+    -- * Storing and retrieving build reports
+    storeAnonymous,
+    storeLocal,
+--    retrieve,
+
+    -- * 'InstallPlan' support
+    fromInstallPlan,
+  ) where
+
+import qualified Distribution.Client.BuildReports.Anonymous as BuildReport
+import Distribution.Client.BuildReports.Anonymous (BuildReport)
+
+import Distribution.Client.Types
+         ( ConfiguredPackage(..), AvailablePackage(..)
+         , AvailablePackageSource(..), Repo(..), RemoteRepo(..) )
+import qualified Distribution.Client.InstallPlan as InstallPlan
+import Distribution.Client.InstallPlan
+         ( InstallPlan, PlanPackage )
+import Distribution.Client.Config
+         ( defaultCabalDir )
+
+import Distribution.System
+         ( OS, Arch )
+import Distribution.Compiler
+         ( CompilerId )
+import Distribution.Simple.Utils
+         ( comparing, equating )
+
+import Data.List
+         ( groupBy, sortBy )
+import Data.Maybe
+         ( catMaybes )
+import System.FilePath
+         ( (</>) )
+
+storeAnonymous :: [(BuildReport, Repo)] -> IO ()
+storeAnonymous reports = sequence_
+  [ appendFile file (concatMap format reports')
+  | (repo, reports') <- separate reports
+  , let file = repoLocalDir repo </> "build-reports.log" ]
+  --TODO: make this concurrency safe, either lock the report file or make sure
+  -- the writes for each report are atomic (under 4k and flush at boundaries)
+
+  where
+    format r = '\n' : BuildReport.show r ++ "\n"
+    separate :: [(BuildReport, Repo)]
+             -> [(Repo, [BuildReport])]
+    separate = map (\rs@((_,repo,_):_) -> (repo, [ r | (r,_,_) <- rs ]))
+             . map concat
+             . groupBy (equating (repoName . head))
+             . sortBy (comparing (repoName . head))
+             . groupBy (equating repoName)
+             . onlyRemote
+    repoName (_,_,rrepo) = remoteRepoName rrepo
+
+    onlyRemote :: [(BuildReport, Repo)] -> [(BuildReport, Repo, RemoteRepo)]
+    onlyRemote rs =
+      [ (report, repo, remoteRepo)
+      | (report, repo@Repo { repoKind = Left remoteRepo }) <- rs ]
+
+storeLocal :: [(BuildReport, Repo)] -> IO ()
+storeLocal reports = do
+  cabalDir <- defaultCabalDir
+  let file = cabalDir </> "build.log"
+  appendFile file (concatMap (format . fst) reports)
+  --TODO: make this concurrency safe, either lock the report file or make sure
+  -- the writes for each report are atomic (under 4k and flush at boundaries)
+
+  where
+    format r = '\n' : BuildReport.show r ++ "\n"
+
+
+-- ------------------------------------------------------------
+-- * InstallPlan support
+-- ------------------------------------------------------------
+
+fromInstallPlan :: InstallPlan -> [(BuildReport, Repo)]
+fromInstallPlan plan = catMaybes
+                     . map (fromPlanPackage os' arch' comp)
+                     . InstallPlan.toList
+                     $ plan
+  where os'   = InstallPlan.planOS plan
+        arch' = InstallPlan.planArch plan
+        comp  = InstallPlan.planCompiler plan
+
+fromPlanPackage :: OS -> Arch -> CompilerId
+                -> InstallPlan.PlanPackage
+                -> Maybe (BuildReport, Repo)
+fromPlanPackage os' arch' comp planPackage = case planPackage of
+
+  InstallPlan.Installed pkg@(ConfiguredPackage (AvailablePackage {
+                          packageSource = RepoTarballPackage repo }) _ _) result
+    -> Just $ (BuildReport.new os' arch' comp pkg (Right result), repo)
+
+  InstallPlan.Failed pkg@(ConfiguredPackage (AvailablePackage {
+                       packageSource = RepoTarballPackage repo }) _ _) result
+    -> Just $ (BuildReport.new os' arch' comp pkg (Left result), repo)
+
+  _ -> Nothing
diff --git a/cabal-install/Distribution/Client/Install.hs b/cabal-install/Distribution/Client/Install.hs
index 9502e6825b..2449fbf23b 100644
--- a/cabal-install/Distribution/Client/Install.hs
+++ b/cabal-install/Distribution/Client/Install.hs
@@ -48,10 +48,8 @@ import Distribution.Client.Types as Available
          , DocsResult(..), TestsResult(..) )
 import Distribution.Client.SetupWrapper
          ( setupWrapper, SetupScriptOptions(..), defaultSetupScriptOptions )
-import Distribution.Client.Reporting
-         ( writeInstallPlanBuildReports )
-import Distribution.Client.Logging
-         ( writeInstallPlanBuildLog )
+import qualified Distribution.Client.BuildReports.Storage as BuildReports
+         ( storeAnonymous, storeLocal, fromInstallPlan )
 import qualified Distribution.Client.InstallSymlink as InstallSymlink
          ( symlinkBinaries )
 import Paths_cabal_install (getBinDir)
@@ -158,8 +156,10 @@ installWithPlanner planner verbosity packageDB repos comp conf configFlags insta
                 installUnpackedPackage verbosity (setupScriptOptions installed)
                                        miscOptions configFlags' installFlags
                                        pkg mpath useLogFile
-        writeInstallPlanBuildReports installPlan'
-        writeInstallPlanBuildLog     installPlan'
+
+        let buildReports = BuildReports.fromInstallPlan installPlan'
+        BuildReports.storeAnonymous buildReports
+        BuildReports.storeLocal     buildReports
         symlinkBinaries verbosity configFlags installFlags installPlan'
         printBuildFailures installPlan'
 
diff --git a/cabal-install/Distribution/Client/Logging.hs b/cabal-install/Distribution/Client/Logging.hs
deleted file mode 100644
index 22f5b952d0..0000000000
--- a/cabal-install/Distribution/Client/Logging.hs
+++ /dev/null
@@ -1,292 +0,0 @@
------------------------------------------------------------------------------
--- |
--- Module      :  Distribution.Client.Logging
--- Copyright   :  (c) David Waern 2008
--- License     :  BSD-like
---
--- Maintainer  :  david.waern@gmail.com
--- Stability   :  experimental
--- Portability :  portable
---
--- Build log data structure
---
------------------------------------------------------------------------------
-module Distribution.Client.Logging (
-    BuildLogEntry(..),
-    InstallOutcome(..),
-    Outcome(..),
-
-    -- * Constructing and writing reports
-    buildLogEntry,
-    writeBuildLog,
-
-    -- * parsing and pretty printing
-    parseBuildLogEntry,
-    parseBuildLog,
-    showBuildLogEntry,
-
-    -- * 'InstallPlan' variants
-    planPackageBuildLogEntry,
-    installPlanBuildLog,
-    writeInstallPlanBuildLog
-  ) where
-
-import Distribution.Client.Reporting
-         ( InstallOutcome(..), Outcome(..) )
-import Distribution.Client.Types
-         ( ConfiguredPackage(..), BuildResult )
-import Distribution.Client.Config
-         ( defaultCabalDir )
-import qualified Distribution.Client.Types as BR
-         ( BuildFailure(..), BuildSuccess(..)
-         , DocsResult(..), TestsResult(..) )
-import qualified Distribution.Client.InstallPlan as InstallPlan
-import Distribution.Client.InstallPlan
-         ( InstallPlan, PlanPackage )
-import Distribution.Client.ParseUtils
-         ( parseFields )
-import qualified Paths_cabal_install (version)
-
-import Distribution.Package
-         ( PackageIdentifier(PackageIdentifier), Package(packageId) )
-import Distribution.PackageDescription
-         ( FlagName(..), FlagAssignment )
---import Distribution.Version
---         ( Version )
-import Distribution.System
-         ( OS, Arch )
-import Distribution.Compiler
-         ( CompilerId )
-import Distribution.Text
-         ( Text(disp, parse) )
-import Distribution.ParseUtils
-         ( FieldDescr(..), ParseResult(..), simpleField, listField, ppFields )
-import qualified Distribution.Compat.ReadP as Parse
-         ( ReadP, {-pfail,-} munch1, char, option )
-import Text.PrettyPrint.HughesPJ as Disp
-         ( Doc, render, char, text, (<>) )
-
-import Data.List
-         ( unfoldr )
-import Data.Maybe
-         ( catMaybes )
-import Data.Char as Char
-         ( isAlphaNum )
-import System.FilePath
-         ( (</>) )
---import Network.URI
---         ( URI, uriToString, parseAbsoluteURI )
-
-type BuildLog = [BuildLogEntry]
-
-data BuildLogEntry
-   = BuildLogEntry {
-    -- | The package this build report is about
-    package         :: PackageIdentifier,
-
-    --   Which hackage server this package is from or local
---    server          :: Maybe URI,
-
-    -- | The OS and Arch the package was built on
-    os              :: OS,
-    arch            :: Arch,
-
-    -- | The Haskell compiler (and hopefully version) used
-    compiler        :: CompilerId,
-
-    -- | The uploading client, ie cabal-install-x.y.z
-    client          :: PackageIdentifier,
-
-    -- | Which configurations flags we used
-    flagAssignment  :: FlagAssignment,
-
-    -- | Which dependent packages we were using exactly
-    dependencies    :: [PackageIdentifier],
-
-    -- | Did installing work ok?
-    installOutcome  :: InstallOutcome,
-
-    --   Which version of the Cabal library was used to compile the Setup.hs
---    cabalVersion    :: Version,
-
-    --   Which build tools we were using (with versions)
---    tools      :: [PackageIdentifier],
-
-    -- | Configure outcome, did configure work ok?
-    docsOutcome     :: Outcome,
-
-    -- | Configure outcome, did configure work ok?
-    testsOutcome    :: Outcome
-  }
-
-writeBuildLog :: BuildLog -> IO ()
-writeBuildLog reports = do
-  cabalDir <- defaultCabalDir
-  let file = cabalDir </> "build.log"
-  appendFile file (concatMap format reports)
-  --TODO: make this concurrency safe, either lock the report file or make sure
-  -- the writes for each report are atomic (under 4k and flush at boundaries)
-
-  where
-    format r = '\n' : showBuildLogEntry r ++ "\n"
-
-buildLogEntry :: OS -> Arch -> CompilerId -- -> Version
-              -> ConfiguredPackage -> BuildResult
-              -> BuildLogEntry
-buildLogEntry os' arch' comp (ConfiguredPackage pkg flags deps) result =
-  BuildLogEntry {
-    package               = packageId pkg,
---    server                = Nothing,
-    os                    = os',
-    arch                  = arch',
-    compiler              = comp,
-    client                = cabalInstallID,
-    flagAssignment        = flags,
-    dependencies          = deps,
-    installOutcome        = convertInstallOutcome,
---    cabalVersion          = undefined
-    docsOutcome           = convertDocsOutcome,
-    testsOutcome          = convertTestsOutcome
-  }
-  where
-    cabalInstallID =
-      PackageIdentifier "cabal-install" Paths_cabal_install.version
-
-    convertInstallOutcome = case result of
-      Left  (BR.DependentFailed p) -> DependencyFailed p
-      Left  (BR.UnpackFailed    _) -> UnpackFailed
-      Left  (BR.ConfigureFailed _) -> ConfigureFailed
-      Left  (BR.BuildFailed     _) -> BuildFailed
-      Left  (BR.InstallFailed   _) -> InstallFailed
-      Right (BR.BuildOk       _ _) -> InstallOk
-    convertDocsOutcome = case result of
-      Left _                                -> NotTried
-      Right (BR.BuildOk BR.DocsNotTried _)  -> NotTried
-      Right (BR.BuildOk BR.DocsFailed _)    -> Failed
-      Right (BR.BuildOk BR.DocsOk _)        -> Ok
-    convertTestsOutcome = case result of
-      Left _                                -> NotTried
-      Right (BR.BuildOk _ BR.TestsNotTried) -> NotTried
-      Right (BR.BuildOk _ BR.TestsFailed)   -> Failed
-      Right (BR.BuildOk _ BR.TestsOk)       -> Ok
-
--- ------------------------------------------------------------
--- * External format
--- ------------------------------------------------------------
-
-initialBuildLogEntry :: BuildLogEntry
-initialBuildLogEntry = BuildLogEntry {
-    package         = requiredField "package",
---    server          = Nothing,
-    os              = requiredField "os",
-    arch            = requiredField "arch",
-    compiler        = requiredField "compiler",
-    client          = requiredField "client",
-    flagAssignment  = [],
-    dependencies    = [],
-    installOutcome  = requiredField "install-outcome",
---    cabalVersion  = Nothing,
---    tools         = [],
-    docsOutcome     = NotTried,
-    testsOutcome    = NotTried
-  }
-  where
-    requiredField fname = error ("required field: " ++ fname)
-
--- -----------------------------------------------------------------------------
--- Parsing
-
-parseBuildLogEntry :: String -> ParseResult BuildLogEntry
-parseBuildLogEntry = parseFields fieldDescrs initialBuildLogEntry
-
-parseBuildLog :: String -> [BuildLogEntry]
-parseBuildLog str =
-  [ report | ParseOk [] report <- map parseBuildLogEntry (split str) ]
-
-  where
-    split :: String -> [String]
-    split = filter (not . null) . unfoldr chunk . lines
-    chunk [] = Nothing
-    chunk ls = case break null ls of
-                 (r, rs) -> Just (unlines r, dropWhile null rs)
-
--- -----------------------------------------------------------------------------
--- Pretty-printing
-
-showBuildLogEntry :: BuildLogEntry -> String
-showBuildLogEntry e = Disp.render (ppFields e fieldDescrs)
-
--- -----------------------------------------------------------------------------
--- Description of the fields, for parsing/printing
-
-fieldDescrs :: [FieldDescr BuildLogEntry]
-fieldDescrs =
- [ simpleField "package"         disp           parse
-                                 package        (\v r -> r { package = v })
--- , simpleField "server"          disp           parse
---                                 server         (\v r -> r { server = v })
- , simpleField "os"              disp           parse
-                                 os             (\v r -> r { os = v })
- , simpleField "arch"            disp           parse
-                                 arch           (\v r -> r { arch = v })
- , simpleField "compiler"        disp           parse
-                                 compiler       (\v r -> r { compiler = v })
- , simpleField "client"          disp           parse
-                                 client         (\v r -> r { client = v })
- , listField   "flags"           dispFlag       parseFlag
-                                 flagAssignment (\v r -> r { flagAssignment = v })
- , listField   "dependencies"    disp           parse
-                                 dependencies   (\v r -> r { dependencies = v })
- , simpleField "install-outcome" disp           parse
-                                 installOutcome (\v r -> r { installOutcome = v })
- , simpleField "docs-outcome"    disp           parse
-                                 docsOutcome    (\v r -> r { docsOutcome = v })
- , simpleField "tests-outcome"   disp           parse
-                                 testsOutcome   (\v r -> r { testsOutcome = v })
- ]
-
-dispFlag :: (FlagName, Bool) -> Disp.Doc
-dispFlag (FlagName name, True)  =                  Disp.text name
-dispFlag (FlagName name, False) = Disp.char '-' <> Disp.text name
-
-parseFlag :: Parse.ReadP r (FlagName, Bool)
-parseFlag = do
-  value <- Parse.option True (Parse.char '-' >> return False)
-  name  <- Parse.munch1 (\c -> Char.isAlphaNum c || c == '_' || c == '-')
-  return (FlagName name, value)
-
-{-
-instance Text URI where
-  disp uri = Disp.text (uriToString id uri [])
-  parse = do
-    str <- Parse.munch1 (\c -> isAlphaNum c || c `elem` "+-=._/*()@'$:;&!?")
-    maybe Parse.pfail return (parseAbsoluteURI str)
--}
--- ------------------------------------------------------------
--- * InstallPlan support
--- ------------------------------------------------------------
-
-writeInstallPlanBuildLog :: InstallPlan -> IO ()
-writeInstallPlanBuildLog = writeBuildLog . installPlanBuildLog
-
-installPlanBuildLog :: InstallPlan -> BuildLog
-installPlanBuildLog plan = catMaybes
-                             . map (planPackageBuildLogEntry os' arch' comp)
-                             . InstallPlan.toList
-                             $ plan
-  where os'   = InstallPlan.planOS plan
-        arch' = InstallPlan.planArch plan
-        comp  = InstallPlan.planCompiler plan
-
-planPackageBuildLogEntry :: OS -> Arch -> CompilerId
-                         -> InstallPlan.PlanPackage
-                         -> Maybe BuildLogEntry
-planPackageBuildLogEntry os' arch' comp planPackage = case planPackage of
-
-  InstallPlan.Installed pkg result
-    -> Just $ buildLogEntry os' arch' comp pkg (Right result)
-
-  InstallPlan.Failed pkg result
-    -> Just $ buildLogEntry os' arch' comp pkg (Left result)
-
-  _ -> Nothing
-- 
GitLab