{- git-annex debugging
-
- - Copyright 2021 Joey Hess <id@joeyh.name>
+ - Copyright 2021-2023 Joey Hess <id@joeyh.name>
-
- Licensed under the GNU AGPL version 3 or higher.
-}
module Annex.Debug (
DebugSelector(..),
DebugSource(..),
+ RawDebugMessage(..),
debug,
+ debug',
fastDebug,
+ fastDebug',
configureDebug,
debugSelectorFromGitConfig,
parseDebugSelector,
import Common
import qualified Annex
-import Utility.Debug hiding (fastDebug)
+import Utility.Debug hiding (fastDebug, fastDebug')
import qualified Utility.Debug
import Annex.Debug.Utility
-- is read from the Annex monad, which avoids any IORef access overhead
-- when debugging is not enabled.
fastDebug :: DebugSource -> String -> Annex.Annex ()
-fastDebug src msg = do
+fastDebug = fastDebug'
+
+fastDebug' :: DebugMessage msg => DebugSource -> msg -> Annex.Annex ()
+fastDebug' src msg = do
rd <- Annex.getRead id
when (Annex.debugenabled rd) $
- liftIO $ Utility.Debug.fastDebug (Annex.debugselector rd) src msg
+ liftIO $ Utility.Debug.fastDebug' (Annex.debugselector rd) src msg
+
outputMessage,
withMessageState,
MessageState,
+ explain,
prompt,
mkPrompter,
sanitizeTopLevelExceptionMessages,
S.hPutStr stderr (safeOutput s <> "\n")
hFlush stderr
+explain :: Maybe String -> String -> Annex ()
+explain Nothing _ = return ()
+explain (Just f) msg = fastDebug' "explain" $
+ RawDebugMessage ('[' : f ++ " " ++ msg ++ "]")
+
{- Should commands that normally output progress messages have that
- output disabled? -}
commandProgressDisabled :: Annex Bool
{- Debug output
-
- - Copyright 2021 Joey Hess <id@joeyh.name>
+ - Copyright 2021-2023 Joey Hess <id@joeyh.name>
-
- License: BSD-2-clause
-}
module Utility.Debug (
DebugSource(..),
DebugSelector(..),
+ DebugMessage,
+ RawDebugMessage(..),
configureDebug,
getDebugSelector,
debug,
- fastDebug
+ debug',
+ fastDebug,
+ fastDebug'
) where
import qualified Data.ByteString as S
instance Monoid DebugSelector where
mempty = NoDebugSelector
+class DebugMessage msg where
+ formatDebugMessage :: DebugSource -> msg -> IO S.ByteString
+
+instance DebugMessage String where
+ formatDebugMessage (DebugSource src) msg = do
+ t <- encodeBS . formatTime defaultTimeLocale "[%F %X%Q]"
+ <$> getZonedTime
+ return (t <> " (" <> src <> ") " <> encodeBS msg)
+
+-- Debug message to be displayed without the usual time stamp
+-- and source information.
+newtype RawDebugMessage = RawDebugMessage String
+
+instance DebugMessage RawDebugMessage where
+ formatDebugMessage _ (RawDebugMessage msg) = pure (encodeBS msg)
+
-- | Configures debugging.
configureDebug
:: (S.ByteString -> IO ())
-- have to consult a IORef each time, using it in a tight loop may slow
-- down the program.
debug :: DebugSource -> String -> IO ()
-debug src msg = readIORef debugConfigGlobal >>= \case
+debug = debug'
+
+debug' :: DebugMessage msg => DebugSource -> msg -> IO ()
+debug' src msg = readIORef debugConfigGlobal >>= \case
(displayer, NoDebugSelector) ->
displayer =<< formatDebugMessage src msg
(displayer, DebugSelector p)
-- When the DebugSelector does not let the message be displayed, this runs
-- very quickly, allowing it to be used inside tight loops.
fastDebug :: DebugSelector -> DebugSource -> String -> IO ()
-fastDebug NoDebugSelector src msg = do
+fastDebug = fastDebug'
+
+fastDebug' :: DebugMessage msg => DebugSelector -> DebugSource -> msg -> IO ()
+fastDebug' NoDebugSelector src msg = do
(displayer, _) <- readIORef debugConfigGlobal
displayer =<< formatDebugMessage src msg
-fastDebug (DebugSelector p) src msg
- | p src = fastDebug NoDebugSelector src msg
+fastDebug' (DebugSelector p) src msg
+ | p src = fastDebug' NoDebugSelector src msg
| otherwise = return ()
-
-formatDebugMessage :: DebugSource -> String -> IO S.ByteString
-formatDebugMessage (DebugSource src) msg = do
- t <- encodeBS . formatTime defaultTimeLocale "[%F %X%Q]"
- <$> getZonedTime
- return (t <> " (" <> src <> ") " <> encodeBS msg)