proteome-0.9.9.9: lib/Proteome/Diag.hs
module Proteome.Diag where
import qualified Data.Map.Strict as Map
import qualified Data.Text as Text
import Exon (exon)
import Path (toFilePath)
import Prettyprinter (Doc, line, nest, pretty, vsep)
import Ribosome (
Handler,
Report (Report),
ReportContext,
Reports,
RpcError,
Scratch,
ScratchId (ScratchId),
Settings,
StoredReport (StoredReport),
reportContext,
resumeReport,
scratch,
storedReports,
)
import qualified Ribosome.Scratch as Scratch
import Ribosome.Scratch (ScratchOptions (filetype, focus))
import qualified Proteome.Data.Env as Env
import Proteome.Data.Env (Env)
import Proteome.Data.Project (Project (Project))
import Proteome.Data.ProjectLang (ProjectLang (ProjectLang, unProjectLang))
import Proteome.Data.ProjectMetadata (ProjectMetadata (DirProject, VirtualProject))
import Proteome.Data.ProjectName (ProjectName (ProjectName))
import Proteome.Data.ProjectRoot (ProjectRoot (ProjectRoot))
import Proteome.Data.ProjectType (ProjectType (ProjectType, unProjectType))
import Proteome.Tags.Gen (tagsCommand)
formatLang :: Maybe ProjectLang -> Text
formatLang (Just (ProjectLang lang)) = lang
formatLang Nothing = "none"
formatType :: Maybe ProjectType -> Text
formatType (Just (ProjectType tpe)) = tpe
formatType Nothing = "none"
formatProject :: ProjectName -> ProjectRoot -> Maybe ProjectType -> [Text]
formatProject (ProjectName name) (ProjectRoot root) tpe =
[
"name: " <> name,
"root: " <> (toText . toFilePath) root,
"type: " <> formatType tpe
]
formatMeta ::
Member (Settings !! se) r =>
ProjectMetadata ->
[ProjectLang] ->
Sem r [Text]
formatMeta (VirtualProject (ProjectName name)) _ =
pure ["name: " <> name]
formatMeta (DirProject name root tpe) langs = do
tags :: [Text] <- resumeAs [] do
runStop (tagsCommand root langs) >>= \case
Right (tagsCmd, tagsArgs) ->
pure [[exon|tags cmd: #{tagsCmd} #{tagsArgs}|]]
Left _ ->
pure []
pure (formatProject name root tpe <> tags)
formatMain ::
Member (Settings !! se) r =>
Project ->
Sem r [Text]
formatMain (Project meta types lang langs) = do
metaContent <- formatMeta meta langs
pure $ metaContent <> [
"types: " <> Text.intercalate ", " (unProjectType <$> types),
"main language: " <> formatLang lang,
"languages: " <> Text.intercalate ", " (unProjectLang <$> langs)
]
formatExtraProjects ::
Member (Settings !! se) r =>
[Project] ->
Sem r [Text]
formatExtraProjects projects = do
formatted <- traverse formatMain projects
pure $ ["", "Extra projects", ""] <> intercalate [""] formatted
formatExtraProjectsIfNonempty ::
Members [Settings !! se, AtomicState Env] r =>
Sem r [Text]
formatExtraProjectsIfNonempty = do
projects <- atomicGets Env.projects
case projects of
_ : _ -> formatExtraProjects projects
_ -> pure []
storedError :: StoredReport -> Doc a
storedError (StoredReport (Report _ log _) _) =
case log of
[] -> mempty
(h : t) ->
nest 2 (vsep (pretty <$> ([exon|* #{h}|] : t)))
tagErrors :: ReportContext -> [StoredReport] -> Doc a
tagErrors ctx errs =
pretty [exon|### #{reportContext ctx}|] <> line <> vsep (storedError <$> errs)
errorDiagnostics :: Map ReportContext [StoredReport] -> Doc a
errorDiagnostics errs | null errs =
mempty
errorDiagnostics errs =
"## Reports" <> line <> line <> vsep (uncurry tagErrors <$> Map.toAscList errs)
diagnostics ::
Members [Settings !! se, AtomicState Env, Reports] r =>
Sem r [Text]
diagnostics = do
main <- formatMain =<< atomicGets Env.mainProject
extra <- formatExtraProjectsIfNonempty
confLog <- atomicGets Env.configLog
errors <- errorDiagnostics <$> storedReports
pure $ header <> main <> extra <> ["", "loaded config files:"] <> confLog <> Text.lines (show errors)
where
header =
["Diagnostics", "", "Main project", ""]
proDiag ::
Members [Settings !! se, Scratch !! RpcError, AtomicState Env, Reports] r =>
Handler r ()
proDiag = do
resumeReport @Scratch do
content <- diagnostics
void $ Scratch.show content options
where
options =
(scratch (ScratchId name)) {
focus = True,
filetype = Just name
}
name =
"proteome-diagnostics"