mirror of
https://github.com/simonmichael/hledger.git
synced 2024-12-27 12:24:43 +03:00
imp: lib: Hledger.Utils.Debug: fix debug logging to file
dlog has been replaced by more reliable functions for debug-logging to a file, useful for debugging TUI apps like hledger-ui: dlogTrace dlogTraceAt dlogAt dlog0 dlog1 dlog2 dlog3 dlog4 dlog5 dlog6 dlog7 dlog8 dlog9 Monochrome pprint' and pshow' have been added. New dependency: deepseq
This commit is contained in:
parent
efa1879a11
commit
b7b09f991a
@ -41,7 +41,9 @@ Debug level: What to show:
|
||||
module Hledger.Utils.Debug (
|
||||
-- * Pretty printing
|
||||
pprint
|
||||
,pprint'
|
||||
,pshow
|
||||
,pshow'
|
||||
-- * Tracing
|
||||
,traceWith
|
||||
-- * Pretty tracing
|
||||
@ -93,9 +95,23 @@ module Hledger.Utils.Debug (
|
||||
,module Debug.Trace
|
||||
,useColorOnStdout
|
||||
,useColorOnStderr
|
||||
,dlog)
|
||||
,dlogTrace
|
||||
,dlogTraceAt
|
||||
,dlogAt
|
||||
,dlog0
|
||||
,dlog1
|
||||
,dlog2
|
||||
,dlog3
|
||||
,dlog4
|
||||
,dlog5
|
||||
,dlog6
|
||||
,dlog7
|
||||
,dlog8
|
||||
,dlog9
|
||||
)
|
||||
where
|
||||
|
||||
import Control.DeepSeq (force)
|
||||
import Control.Monad (when)
|
||||
import Control.Monad.IO.Class
|
||||
import Data.List hiding (uncons)
|
||||
@ -113,25 +129,38 @@ import Text.Pretty.Simple -- (defaultOutputOptionsDarkBg, OutputOptio
|
||||
import Data.Maybe (isJust)
|
||||
import System.Console.ANSI (hSupportsANSIColor)
|
||||
import System.IO (stdout, Handle, stderr)
|
||||
import Control.Exception (evaluate)
|
||||
|
||||
-- | pretty-simple options with colour enabled if allowed.
|
||||
prettyopts =
|
||||
baseopts
|
||||
(if useColorOnStderr then defaultOutputOptionsDarkBg else defaultOutputOptionsNoColor)
|
||||
{ outputOptionsIndentAmount=2
|
||||
, outputOptionsCompact=True
|
||||
}
|
||||
|
||||
-- | pretty-simple options with colour disabled.
|
||||
prettyopts' =
|
||||
defaultOutputOptionsNoColor
|
||||
{ outputOptionsIndentAmount=2
|
||||
, outputOptionsCompact=True
|
||||
}
|
||||
where
|
||||
baseopts
|
||||
| useColorOnStderr = defaultOutputOptionsDarkBg -- defaultOutputOptionsLightBg
|
||||
| otherwise = defaultOutputOptionsNoColor
|
||||
|
||||
-- | Pretty print. Generic alias for pretty-simple's pPrint.
|
||||
pprint :: Show a => a -> IO ()
|
||||
pprint = pPrintOpt CheckColorTty prettyopts
|
||||
|
||||
-- | Monochrome version of pprint.
|
||||
pprint' :: Show a => a -> IO ()
|
||||
pprint' = pPrintOpt CheckColorTty prettyopts'
|
||||
|
||||
-- | Pretty show. Generic alias for pretty-simple's pShow.
|
||||
pshow :: Show a => a -> String
|
||||
pshow = TL.unpack . pShowOpt prettyopts
|
||||
|
||||
-- | Monochrome version of pshow.
|
||||
pshow' :: Show a => a -> String
|
||||
pshow' = TL.unpack . pShowOpt prettyopts'
|
||||
|
||||
-- XXX some of the below can be improved with pretty-simple, https://github.com/cdepillabout/pretty-simple#readme
|
||||
|
||||
-- | Pretty trace. Easier alias for traceShowId + pShow.
|
||||
@ -284,8 +313,7 @@ traceAtWith level f a = traceAt level (f a) a
|
||||
ptraceAt :: Show a => Int -> String -> a -> a
|
||||
ptraceAt level
|
||||
| level > 0 && debugLevel < level = const id
|
||||
| otherwise = \s a -> let p = pshow a
|
||||
ls = lines p
|
||||
| otherwise = \s a -> let ls = lines $ pshow a
|
||||
nlorspace | length ls > 1 = "\n"
|
||||
| otherwise = replicate (max 1 $ 11 - length s) ' '
|
||||
ls' | length ls > 1 = map (' ':) ls
|
||||
@ -305,10 +333,6 @@ ptraceAtWith level f
|
||||
-- in trace (s++":"++nlorspace++intercalate "\n" ls') a
|
||||
in trace p a
|
||||
|
||||
-- | Log a pretty-printed showable value to "./debug.log". Uses unsafePerformIO.
|
||||
dlog :: Show a => a -> a
|
||||
dlog x = unsafePerformIO $ appendFile "debug.log" (pshow x ++ "\n") >> return x
|
||||
|
||||
-- "dbg" would clash with megaparsec.
|
||||
-- | Pretty-print a label and the showable value to the console, then return it.
|
||||
dbg0 :: Show a => String -> a -> a
|
||||
@ -344,6 +368,7 @@ dbg9 :: Show a => String -> a -> a
|
||||
dbg9 = ptraceAt 9
|
||||
|
||||
-- | Like dbg0, but also exit the program. Uses unsafePerformIO.
|
||||
-- {-# NOINLINE dbgExit #-}
|
||||
dbgExit :: Show a => String -> a -> a
|
||||
dbgExit msg = const (unsafePerformIO exitFailure) . dbg0 msg
|
||||
|
||||
@ -420,6 +445,70 @@ dbg8IO = ptraceAtIO 8
|
||||
dbg9IO :: (MonadIO m, Show a) => String -> a -> m ()
|
||||
dbg9IO = ptraceAtIO 9
|
||||
|
||||
-- | Log a string to ./debug.log before returning the second argument.
|
||||
-- Uses unsafePerformIO.
|
||||
-- {-# NOINLINE dlogTrace #-}
|
||||
dlogTrace :: String -> a -> a
|
||||
dlogTrace s x = unsafePerformIO $ do
|
||||
evaluate (force s) -- to complete any previous logging before we attempt more
|
||||
appendFile "debug.log" (s ++ "\n")
|
||||
return x
|
||||
|
||||
-- | Log a string to ./debug.log before returning the second argument,
|
||||
-- if the global debug level is at or above the specified level.
|
||||
-- At level 0, always logs. Otherwise, uses unsafePerformIO.
|
||||
dlogTraceAt :: Int -> String -> a -> a
|
||||
dlogTraceAt level s
|
||||
| level > 0 && debugLevel < level = id
|
||||
| otherwise = dlogTrace s
|
||||
|
||||
-- | Log a label and pretty-printed showable value to "./debug.log",
|
||||
-- if the global debug level is at or above the specified level.
|
||||
-- At level 0, always prints. Otherwise, uses unsafePerformIO.
|
||||
dlogAt :: Show a => Int -> String -> a -> a
|
||||
dlogAt level
|
||||
| level > 0 && debugLevel < level = const id
|
||||
| otherwise = \lbl a ->
|
||||
let
|
||||
ls = lines $ pshow' a
|
||||
nlorspace | length ls > 1 = "\n"
|
||||
| otherwise = replicate (max 1 $ 11 - length lbl) ' '
|
||||
ls' | length ls > 1 = map (' ':) ls
|
||||
| otherwise = ls
|
||||
in dlogTrace (lbl++":"++nlorspace++intercalate "\n" ls') a
|
||||
|
||||
-- | Pretty-print a label and the showable value to ./debug.log if at or above
|
||||
-- a certain debug level, then return it.
|
||||
dlog0 :: Show a => String -> a -> a
|
||||
dlog0 = dlogAt 0
|
||||
|
||||
dlog1 :: Show a => String -> a -> a
|
||||
dlog1 = dlogAt 1
|
||||
|
||||
dlog2 :: Show a => String -> a -> a
|
||||
dlog2 = dlogAt 2
|
||||
|
||||
dlog3 :: Show a => String -> a -> a
|
||||
dlog3 = dlogAt 3
|
||||
|
||||
dlog4 :: Show a => String -> a -> a
|
||||
dlog4 = dlogAt 4
|
||||
|
||||
dlog5 :: Show a => String -> a -> a
|
||||
dlog5 = dlogAt 5
|
||||
|
||||
dlog6 :: Show a => String -> a -> a
|
||||
dlog6 = dlogAt 6
|
||||
|
||||
dlog7 :: Show a => String -> a -> a
|
||||
dlog7 = dlogAt 7
|
||||
|
||||
dlog8 :: Show a => String -> a -> a
|
||||
dlog8 = dlogAt 8
|
||||
|
||||
dlog9 :: Show a => String -> a -> a
|
||||
dlog9 = dlogAt 9
|
||||
|
||||
-- | Print the provided label (if non-null) and current parser state
|
||||
-- (position and next input) to the console. See also megaparsec's dbg.
|
||||
traceParse :: String -> TextParser m ()
|
||||
|
@ -45,6 +45,7 @@ dependencies:
|
||||
- cassava
|
||||
- cassava-megaparsec
|
||||
- data-default >=0.5
|
||||
- deepseq
|
||||
- Decimal >=0.5.1
|
||||
- directory
|
||||
- doclayout >=0.3 && <0.5
|
||||
|
Loading…
Reference in New Issue
Block a user