1 {-# LANGUAGE FlexibleContexts #-}
2 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
3 {-# LANGUAGE Rank2Types #-}
5 module Distribution
.Utils
.LogProgress
14 import Distribution
.Compat
.Prelude
17 import Distribution
.Simple
.Utils
18 import Distribution
.Utils
.Progress
19 import Distribution
.Verbosity
20 import Text
.PrettyPrint
27 { le_verbosity
:: Verbosity
28 , le_context
:: [CtxMsg
]
31 -- | The 'Progress' monad with specialized logging and
33 newtype LogProgress a
= LogProgress
{unLogProgress
:: LogEnv
-> Progress LogMsg ErrMsg a
}
35 instance Functor LogProgress
where
36 fmap f
(LogProgress m
) = LogProgress
(fmap (fmap f
) m
)
38 instance Applicative LogProgress
where
39 pure x
= LogProgress
(pure
(pure x
))
40 LogProgress f
<*> LogProgress x
= LogProgress
$ \r -> f r `
ap` x r
42 instance Monad LogProgress
where
44 LogProgress m
>>= f
= LogProgress
$ \r -> m r
>>= \x
-> unLogProgress
(f x
) r
46 -- | Run 'LogProgress', outputting traces according to 'Verbosity',
47 -- 'die' if there is an error.
48 runLogProgress
:: Verbosity
-> LogProgress a
-> IO a
49 runLogProgress verbosity
(LogProgress m
) =
50 foldProgress step_fn fail_fn
return (m env
)
54 { le_verbosity
= verbosity
57 step_fn
:: LogMsg
-> IO a
-> IO a
61 fail_fn
:: Doc
-> IO a
63 dieNoWrap verbosity
(render doc
)
65 -- | Output a warning trace message in 'LogProgress'.
66 warnProgress
:: Doc
-> LogProgress
()
67 warnProgress s
= LogProgress
$ \env
->
68 when (le_verbosity env
>= normal
) $
70 hang
(text
"Warning:") 4 (formatMsg
(le_context env
) s
)
72 -- | Output an informational trace message in 'LogProgress'.
73 infoProgress
:: Doc
-> LogProgress
()
74 infoProgress s
= LogProgress
$ \env
->
75 when (le_verbosity env
>= verbose
) $
78 -- | Fail the computation with an error message.
79 dieProgress
:: Doc
-> LogProgress a
80 dieProgress s
= LogProgress
$ \env
->
82 hang
(text
"Error:") 4 (formatMsg
(le_context env
) s
)
84 -- | Format a message with context. (Something simple for now.)
85 formatMsg
:: [CtxMsg
] -> Doc
-> Doc
86 formatMsg ctx doc
= doc
$$ vcat ctx
88 -- | Add a message to the error/warning context.
89 addProgressCtx
:: CtxMsg
-> LogProgress a
-> LogProgress a
90 addProgressCtx s
(LogProgress m
) = LogProgress
$ \env
->
91 m env
{le_context
= s
: le_context env
}