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 ( | module Hledger.Utils.Debug ( | ||||||
|   -- * Pretty printing |   -- * Pretty printing | ||||||
|    pprint |    pprint | ||||||
|  |   ,pprint' | ||||||
|   ,pshow |   ,pshow | ||||||
|  |   ,pshow' | ||||||
|   -- * Tracing |   -- * Tracing | ||||||
|   ,traceWith |   ,traceWith | ||||||
|   -- * Pretty tracing |   -- * Pretty tracing | ||||||
| @ -93,9 +95,23 @@ module Hledger.Utils.Debug ( | |||||||
|   ,module Debug.Trace |   ,module Debug.Trace | ||||||
|   ,useColorOnStdout |   ,useColorOnStdout | ||||||
|   ,useColorOnStderr |   ,useColorOnStderr | ||||||
|   ,dlog) |   ,dlogTrace | ||||||
|  |   ,dlogTraceAt | ||||||
|  |   ,dlogAt | ||||||
|  |   ,dlog0 | ||||||
|  |   ,dlog1 | ||||||
|  |   ,dlog2 | ||||||
|  |   ,dlog3 | ||||||
|  |   ,dlog4 | ||||||
|  |   ,dlog5 | ||||||
|  |   ,dlog6 | ||||||
|  |   ,dlog7 | ||||||
|  |   ,dlog8 | ||||||
|  |   ,dlog9 | ||||||
|  |   ) | ||||||
| where | where | ||||||
| 
 | 
 | ||||||
|  | import           Control.DeepSeq (force) | ||||||
| import           Control.Monad (when) | import           Control.Monad (when) | ||||||
| import           Control.Monad.IO.Class | import           Control.Monad.IO.Class | ||||||
| import           Data.List hiding (uncons) | import           Data.List hiding (uncons) | ||||||
| @ -113,25 +129,38 @@ import           Text.Pretty.Simple  -- (defaultOutputOptionsDarkBg, OutputOptio | |||||||
| import Data.Maybe (isJust) | import Data.Maybe (isJust) | ||||||
| import System.Console.ANSI (hSupportsANSIColor) | import System.Console.ANSI (hSupportsANSIColor) | ||||||
| import System.IO (stdout, Handle, stderr) | import System.IO (stdout, Handle, stderr) | ||||||
|  | import Control.Exception (evaluate) | ||||||
| 
 | 
 | ||||||
|  | -- | pretty-simple options with colour enabled if allowed. | ||||||
| prettyopts =  | prettyopts =  | ||||||
|   baseopts |   (if useColorOnStderr then defaultOutputOptionsDarkBg else defaultOutputOptionsNoColor) | ||||||
|  |     { outputOptionsIndentAmount=2 | ||||||
|  |     , outputOptionsCompact=True | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | -- | pretty-simple options with colour disabled. | ||||||
|  | prettyopts' = | ||||||
|  |   defaultOutputOptionsNoColor | ||||||
|     { outputOptionsIndentAmount=2 |     { outputOptionsIndentAmount=2 | ||||||
|     , outputOptionsCompact=True |     , outputOptionsCompact=True | ||||||
|     } |     } | ||||||
|   where |  | ||||||
|     baseopts |  | ||||||
|       | useColorOnStderr = defaultOutputOptionsDarkBg -- defaultOutputOptionsLightBg |  | ||||||
|       | otherwise        = defaultOutputOptionsNoColor |  | ||||||
| 
 | 
 | ||||||
| -- | Pretty print. Generic alias for pretty-simple's pPrint. | -- | Pretty print. Generic alias for pretty-simple's pPrint. | ||||||
| pprint :: Show a => a -> IO () | pprint :: Show a => a -> IO () | ||||||
| pprint = pPrintOpt CheckColorTty prettyopts | 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. | -- | Pretty show. Generic alias for pretty-simple's pShow. | ||||||
| pshow :: Show a => a -> String | pshow :: Show a => a -> String | ||||||
| pshow = TL.unpack . pShowOpt prettyopts | 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 | -- 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. | -- | 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 :: Show a => Int -> String -> a -> a | ||||||
| ptraceAt level | ptraceAt level | ||||||
|     | level > 0 && debugLevel < level = const id |     | level > 0 && debugLevel < level = const id | ||||||
|     | otherwise = \s a -> let p = pshow a |     | otherwise = \s a -> let ls = lines $ pshow a | ||||||
|                               ls = lines p |  | ||||||
|                               nlorspace | length ls > 1 = "\n" |                               nlorspace | length ls > 1 = "\n" | ||||||
|                                         | otherwise     = replicate (max 1 $ 11 - length s) ' ' |                                         | otherwise     = replicate (max 1 $ 11 - length s) ' ' | ||||||
|                               ls' | length ls > 1 = map (' ':) ls |                               ls' | length ls > 1 = map (' ':) ls | ||||||
| @ -305,10 +333,6 @@ ptraceAtWith level f | |||||||
|                         -- in trace (s++":"++nlorspace++intercalate "\n" ls') a |                         -- in trace (s++":"++nlorspace++intercalate "\n" ls') a | ||||||
|                         in trace p 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. | -- "dbg" would clash with megaparsec. | ||||||
| -- | Pretty-print a label and the showable value to the console, then return it. | -- | Pretty-print a label and the showable value to the console, then return it. | ||||||
| dbg0 :: Show a => String -> a -> a | dbg0 :: Show a => String -> a -> a | ||||||
| @ -344,6 +368,7 @@ dbg9 :: Show a => String -> a -> a | |||||||
| dbg9 = ptraceAt 9 | dbg9 = ptraceAt 9 | ||||||
| 
 | 
 | ||||||
| -- | Like dbg0, but also exit the program. Uses unsafePerformIO. | -- | Like dbg0, but also exit the program. Uses unsafePerformIO. | ||||||
|  | -- {-# NOINLINE dbgExit #-} | ||||||
| dbgExit :: Show a => String -> a -> a | dbgExit :: Show a => String -> a -> a | ||||||
| dbgExit msg = const (unsafePerformIO exitFailure) . dbg0 msg | dbgExit msg = const (unsafePerformIO exitFailure) . dbg0 msg | ||||||
| 
 | 
 | ||||||
| @ -420,6 +445,70 @@ dbg8IO = ptraceAtIO 8 | |||||||
| dbg9IO :: (MonadIO m, Show a) => String -> a -> m () | dbg9IO :: (MonadIO m, Show a) => String -> a -> m () | ||||||
| dbg9IO = ptraceAtIO 9 | 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 | -- | Print the provided label (if non-null) and current parser state | ||||||
| -- (position and next input) to the console. See also megaparsec's dbg. | -- (position and next input) to the console. See also megaparsec's dbg. | ||||||
| traceParse :: String -> TextParser m () | traceParse :: String -> TextParser m () | ||||||
|  | |||||||
| @ -45,6 +45,7 @@ dependencies: | |||||||
| - cassava | - cassava | ||||||
| - cassava-megaparsec | - cassava-megaparsec | ||||||
| - data-default >=0.5 | - data-default >=0.5 | ||||||
|  | - deepseq | ||||||
| - Decimal >=0.5.1 | - Decimal >=0.5.1 | ||||||
| - directory | - directory | ||||||
| - doclayout >=0.3 && <0.5 | - doclayout >=0.3 && <0.5 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user