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