use existing debug machinery for explain
explain is a kind of debug message, but not formatted in the same way. So it makes sense to reuse the debug machinery for it, since that is already quite optimised. Sponsored-by: Dartmouth College's DANDI project
This commit is contained in:
parent
fbf19338be
commit
409572c9e4
3 changed files with 49 additions and 16 deletions
|
@ -1,6 +1,6 @@
|
||||||
{- git-annex debugging
|
{- 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.
|
- Licensed under the GNU AGPL version 3 or higher.
|
||||||
-}
|
-}
|
||||||
|
@ -8,8 +8,11 @@
|
||||||
module Annex.Debug (
|
module Annex.Debug (
|
||||||
DebugSelector(..),
|
DebugSelector(..),
|
||||||
DebugSource(..),
|
DebugSource(..),
|
||||||
|
RawDebugMessage(..),
|
||||||
debug,
|
debug,
|
||||||
|
debug',
|
||||||
fastDebug,
|
fastDebug,
|
||||||
|
fastDebug',
|
||||||
configureDebug,
|
configureDebug,
|
||||||
debugSelectorFromGitConfig,
|
debugSelectorFromGitConfig,
|
||||||
parseDebugSelector,
|
parseDebugSelector,
|
||||||
|
@ -17,7 +20,7 @@ module Annex.Debug (
|
||||||
|
|
||||||
import Common
|
import Common
|
||||||
import qualified Annex
|
import qualified Annex
|
||||||
import Utility.Debug hiding (fastDebug)
|
import Utility.Debug hiding (fastDebug, fastDebug')
|
||||||
import qualified Utility.Debug
|
import qualified Utility.Debug
|
||||||
import Annex.Debug.Utility
|
import Annex.Debug.Utility
|
||||||
|
|
||||||
|
@ -25,7 +28,11 @@ import Annex.Debug.Utility
|
||||||
-- is read from the Annex monad, which avoids any IORef access overhead
|
-- is read from the Annex monad, which avoids any IORef access overhead
|
||||||
-- when debugging is not enabled.
|
-- when debugging is not enabled.
|
||||||
fastDebug :: DebugSource -> String -> Annex.Annex ()
|
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
|
rd <- Annex.getRead id
|
||||||
when (Annex.debugenabled rd) $
|
when (Annex.debugenabled rd) $
|
||||||
liftIO $ Utility.Debug.fastDebug (Annex.debugselector rd) src msg
|
liftIO $ Utility.Debug.fastDebug' (Annex.debugselector rd) src msg
|
||||||
|
|
||||||
|
|
|
@ -50,6 +50,7 @@ module Messages (
|
||||||
outputMessage,
|
outputMessage,
|
||||||
withMessageState,
|
withMessageState,
|
||||||
MessageState,
|
MessageState,
|
||||||
|
explain,
|
||||||
prompt,
|
prompt,
|
||||||
mkPrompter,
|
mkPrompter,
|
||||||
sanitizeTopLevelExceptionMessages,
|
sanitizeTopLevelExceptionMessages,
|
||||||
|
@ -281,6 +282,11 @@ debugDisplayer = do
|
||||||
S.hPutStr stderr (safeOutput s <> "\n")
|
S.hPutStr stderr (safeOutput s <> "\n")
|
||||||
hFlush stderr
|
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
|
{- Should commands that normally output progress messages have that
|
||||||
- output disabled? -}
|
- output disabled? -}
|
||||||
commandProgressDisabled :: Annex Bool
|
commandProgressDisabled :: Annex Bool
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{- Debug output
|
{- Debug output
|
||||||
-
|
-
|
||||||
- Copyright 2021 Joey Hess <id@joeyh.name>
|
- Copyright 2021-2023 Joey Hess <id@joeyh.name>
|
||||||
-
|
-
|
||||||
- License: BSD-2-clause
|
- License: BSD-2-clause
|
||||||
-}
|
-}
|
||||||
|
@ -12,10 +12,14 @@
|
||||||
module Utility.Debug (
|
module Utility.Debug (
|
||||||
DebugSource(..),
|
DebugSource(..),
|
||||||
DebugSelector(..),
|
DebugSelector(..),
|
||||||
|
DebugMessage,
|
||||||
|
RawDebugMessage(..),
|
||||||
configureDebug,
|
configureDebug,
|
||||||
getDebugSelector,
|
getDebugSelector,
|
||||||
debug,
|
debug,
|
||||||
fastDebug
|
debug',
|
||||||
|
fastDebug,
|
||||||
|
fastDebug'
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import qualified Data.ByteString as S
|
import qualified Data.ByteString as S
|
||||||
|
@ -50,6 +54,22 @@ instance Sem.Semigroup DebugSelector where
|
||||||
instance Monoid DebugSelector where
|
instance Monoid DebugSelector where
|
||||||
mempty = NoDebugSelector
|
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.
|
-- | Configures debugging.
|
||||||
configureDebug
|
configureDebug
|
||||||
:: (S.ByteString -> IO ())
|
:: (S.ByteString -> IO ())
|
||||||
|
@ -76,7 +96,10 @@ debugConfigGlobal = unsafePerformIO $ newIORef (dontshow, selectnone)
|
||||||
-- have to consult a IORef each time, using it in a tight loop may slow
|
-- have to consult a IORef each time, using it in a tight loop may slow
|
||||||
-- down the program.
|
-- down the program.
|
||||||
debug :: DebugSource -> String -> IO ()
|
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, NoDebugSelector) ->
|
||||||
displayer =<< formatDebugMessage src msg
|
displayer =<< formatDebugMessage src msg
|
||||||
(displayer, DebugSelector p)
|
(displayer, DebugSelector p)
|
||||||
|
@ -88,15 +111,12 @@ debug src msg = readIORef debugConfigGlobal >>= \case
|
||||||
-- When the DebugSelector does not let the message be displayed, this runs
|
-- When the DebugSelector does not let the message be displayed, this runs
|
||||||
-- very quickly, allowing it to be used inside tight loops.
|
-- very quickly, allowing it to be used inside tight loops.
|
||||||
fastDebug :: DebugSelector -> DebugSource -> String -> IO ()
|
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, _) <- readIORef debugConfigGlobal
|
||||||
displayer =<< formatDebugMessage src msg
|
displayer =<< formatDebugMessage src msg
|
||||||
fastDebug (DebugSelector p) src msg
|
fastDebug' (DebugSelector p) src msg
|
||||||
| p src = fastDebug NoDebugSelector src msg
|
| p src = fastDebug' NoDebugSelector src msg
|
||||||
| otherwise = return ()
|
| 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)
|
|
||||||
|
|
Loading…
Reference in a new issue