debuggable 0.1.0 → 0.1.1
raw patch · 10 files changed
+213/−97 lines, 10 filesdep ~basedep ~containersdep ~optparse-applicativePVP ok
version bump matches the API change (PVP)
Dependency ranges changed: base, containers, optparse-applicative
API changes (from Hackage documentation)
Files
- CHANGELOG.md +5/−0
- debuggable.cabal +10/−7
- demo/Cmdline.hs +84/−36
- demo/Demo.hs +5/−9
- demo/Demo/Callback.hs +18/−11
- demo/Demo/Callback/Profiling.hs +35/−0
- demo/Demo/Callsite.hs +14/−10
- demo/Demo/Invocation.hs +16/−9
- demo/Demo/NIIO.hs +14/−4
- demo/Demo/Scope.hs +12/−11
CHANGELOG.md view
@@ -1,5 +1,10 @@ # Revision history for debuggable +## 0.1.1 -- 2026-06-04++* Relax bounds+* Extend demo+ ## 0.1.0 -- 2024-11-23 * First public release
debuggable.cabal view
@@ -1,6 +1,6 @@ cabal-version: 3.0 name: debuggable-version: 0.1.0+version: 0.1.1 synopsis: Utilities for making your applications more debuggable. description: This package provides various utilities that can be used to make your application easier to debug. Some of these tools are@@ -18,9 +18,11 @@ tested-with: GHC==8.10.7 , GHC==9.2.8 , GHC==9.4.8- , GHC==9.6.6- , GHC==9.8.2- , GHC==9.10.1+ , GHC==9.6.7+ , GHC==9.8.4+ , GHC==9.10.3+ , GHC==9.12.4+ , GHC==9.14.1 source-repository head type: git@@ -28,7 +30,7 @@ common lang default-language: Haskell2010- build-depends: base >= 4.14 && < 4.21+ build-depends: base >= 4.14 && < 4.23 default-extensions: BangPatterns@@ -74,7 +76,7 @@ Debug.Provenance.Internal build-depends:- , containers >= 0.6 && < 0.8+ , containers >= 0.6 && < 0.9 , exceptions >= 0.9 && < 0.11 , hashable >= 1.4 && < 1.6 , temporary >= 1.2.1 && < 1.4@@ -98,6 +100,7 @@ other-modules: Cmdline Demo.Callback+ Demo.Callback.Profiling Demo.Callsite Demo.Invocation Demo.NIIO@@ -110,5 +113,5 @@ build-depends: -- additional dependencies , async >= 2.2 && < 2.3- , optparse-applicative >= 0.18 && < 0.19+ , optparse-applicative >= 0.18 && < 0.20
demo/Cmdline.hs view
@@ -6,7 +6,10 @@ import Options.Applicative +import Demo.Callback qualified as Callback+import Demo.Callsite qualified as Callsite import Demo.Invocation qualified as Invocation+import Demo.NIIO qualified as NIIO import Demo.Scope qualified as Scope {-------------------------------------------------------------------------------@@ -19,15 +22,11 @@ deriving stock (Show) data Demo =- DemoNiioWithout- | DemoNiioUse- | DemoCallsiteWithout- | DemoCallsiteUse- | DemoInvocationWithout- | DemoInvocationUse Invocation.Example- | DemoScopeUse Scope.Example- | DemoCallbackWithout- | DemoCallbackUse+ DemoNiio NIIO.Example+ | DemoCallsite Callsite.Example+ | DemoInvocation Invocation.Example+ | DemoScope Scope.Example+ | DemoCallback Callback.Example deriving stock (Show) getCmdline :: IO Cmdline@@ -52,58 +51,106 @@ parseDemo = subparser $ mconcat [ command' "niio"- ( parseWithoutUse- (pure DemoNiioWithout)- (pure DemoNiioUse)- )+ (DemoNiio <$> parseNiioExample) "Demo Debug.NonInterleavedIO" , command' "callsite"- ( parseWithoutUse- (pure DemoCallsiteWithout)- (pure DemoCallsiteUse)- )+ (DemoCallsite <$> parseCallsiteExample) "Demo CallSite from Debug.Provenance" , command' "invocation"- ( parseWithoutUse- (pure DemoInvocationWithout)- (DemoInvocationUse <$> parseInvocationExample)- )+ (DemoInvocation <$> parseInvocationExample) "Demo Invocation from Debug.Provenance" , command' "scope"- ( DemoScopeUse <$> parseScopeExample )+ (DemoScope <$> parseScopeExample) "Demo Debug.Provenance.Scope" , command' "callback"- ( parseWithoutUse- (pure DemoCallbackWithout)- (pure DemoCallbackUse)- )+ (DemoCallback <$> parseCallbackExample) "Demo Debug.Provenance.Callback" ] -parseWithoutUse :: Parser a -> Parser a -> Parser a-parseWithoutUse without use = subparser $ mconcat [- command' "without-debuggable" without "Without debuggable"- , command' "use-debuggable" use "Use debuggable"+parseNiioExample :: Parser NIIO.Example+parseNiioExample = subparser $ mconcat [+ command'+ "without-debuggable"+ (pure NIIO.WithoutDebuggable)+ "Without debuggable"+ , command'+ "use-debuggable"+ (pure NIIO.UseDebuggable)+ "Use debuggable" ] +parseCallsiteExample :: Parser Callsite.Example+parseCallsiteExample = subparser $ mconcat [+ command'+ "without-debuggable"+ (pure Callsite.WithoutDebuggable)+ "Without debuggable"+ , command'+ "use-debuggable"+ (pure Callsite.UseDebuggable)+ "Use debuggable"+ ]+ parseInvocationExample :: Parser Invocation.Example parseInvocationExample = subparser $ mconcat [- command' "example1" (pure Invocation.Example1) "Example 1"- , command' "example2" (pure Invocation.Example2) "Example 2"+ command'+ "without-debuggable"+ (pure Invocation.WithoutDebuggable)+ "Without debuggable"+ , command'+ "use-debuggable-1"+ (pure $ Invocation.UseDebuggable Invocation.Example1)+ "Use debuggable, example 1"+ , command'+ "use-debuggable-2"+ (pure $ Invocation.UseDebuggable Invocation.Example2)+ "Use debuggable, example 2" ] parseScopeExample :: Parser Scope.Example parseScopeExample = subparser $ mconcat [- command' "example1" (pure Scope.Example1) "Example 1"- , command' "example2" (pure Scope.Example2) "Example 2"- , command' "example3" (pure Scope.Example3) "Example 3"- , command' "example4" (pure Scope.Example4) "Example 4"+ command'+ "example1"+ (pure Scope.Example1)+ "Use debuggable, example 1"+ , command'+ "example2"+ (pure Scope.Example2)+ "Use debuggable, example 2"+ , command'+ "example3"+ (pure Scope.Example3)+ "Use debuggable, example 3"+ , command'+ "example4"+ (pure Scope.Example4)+ "Use debuggable, example 4" ] +parseCallbackExample :: Parser Callback.Example+parseCallbackExample = subparser $ mconcat [+ command'+ "without-debuggable"+ (pure Callback.WithoutDebuggable)+ "Without debuggable"+ , command'+ "use-debuggable"+ (pure Callback.UseDebuggable)+ "Use debuggable"+ , command'+ "use-profiling-1"+ (pure $ Callback.UseProfiling Nothing)+ "Use profiling, example 1"+ , command'+ "use-profiling-2"+ (Callback.UseProfiling . Just <$> argument auto (metavar "INT"))+ "Use profiling, example 2"+ ]+ {------------------------------------------------------------------------------- Auxiliary optparse-applicative -------------------------------------------------------------------------------}@@ -112,3 +159,4 @@ command' cmd parser desc = command cmd $ info (parser <**> helper) $ mconcat [ progDesc desc ]+
demo/Demo.hs view
@@ -15,13 +15,9 @@ Nothing -> putStrLn "Please select a demo (see --help)" Just demo -> case demo of- DemoNiioWithout -> NIIO.withoutDebuggable- DemoNiioUse -> NIIO.useDebuggable- DemoCallsiteWithout -> Callsite.withoutDebuggable- DemoCallsiteUse -> Callsite.useDebuggable- DemoInvocationWithout -> Invocation.withoutDebuggable- DemoInvocationUse ex -> Invocation.useDebuggable ex- DemoScopeUse ex -> Scope.useDebuggable ex- DemoCallbackWithout -> Callback.withoutDebuggable- DemoCallbackUse -> Callback.useDebuggable+ DemoNiio ex -> NIIO.demo ex+ DemoCallsite ex -> Callsite.demo ex+ DemoInvocation ex -> Invocation.demo ex+ DemoScope ex -> Scope.demo ex+ DemoCallback ex -> Callback.demo ex
demo/Demo/Callback.hs view
@@ -1,7 +1,4 @@-module Demo.Callback (- withoutDebuggable- , useDebuggable- ) where+module Demo.Callback (Example(..), demo) where import GHC.Stack @@ -9,7 +6,24 @@ import Debug.Provenance.Callback import Debug.Provenance.Scope +import Demo.Callback.Profiling qualified as Profiling+ {-------------------------------------------------------------------------------+ Top-level+-------------------------------------------------------------------------------}++data Example =+ WithoutDebuggable+ | UseDebuggable+ | UseProfiling (Maybe Int)+ deriving stock (Show)++demo :: Example -> IO ()+demo WithoutDebuggable = f1 g1+demo UseDebuggable = h1 (callback g1)+demo (UseProfiling i) = Profiling.demo i++{------------------------------------------------------------------------------- Without the library -------------------------------------------------------------------------------} @@ -25,9 +39,6 @@ g2 :: HasCallStack => Int -> IO () g2 n = Scoped.putStrLn $ "n = " ++ show n ++ " at " ++ prettyCallStack callStack -withoutDebuggable :: HasCallStack => IO ()-withoutDebuggable = f1 g1- {------------------------------------------------------------------------------- Using the library -------------------------------------------------------------------------------}@@ -37,7 +48,3 @@ h2 :: HasCallStack => Callback IO Int () -> IO () h2 k = scoped $ invokeCallback k 1--useDebuggable :: HasCallStack => IO ()-useDebuggable = h1 (callback g1)-
+ demo/Demo/Callback/Profiling.hs view
@@ -0,0 +1,35 @@+-- | Profiling version of the callback demo+--+-- Requires the code to be built with profiling info.+module Demo.Callback.Profiling (demo) where++import GHC.Stack++{-------------------------------------------------------------------------------+ Top-level+-------------------------------------------------------------------------------}++demo :: Maybe Int -> IO ()+demo Nothing = f1 (\x -> g1 x)+demo (Just i) = f1 (\x -> g1 (x + i))++{-------------------------------------------------------------------------------+ Demo proper+-------------------------------------------------------------------------------}++f1 :: (Int -> IO ()) -> IO ()+f1 k = do+ cs <- whoCreated k+ putStrLn $ "f1: invoking callback defined at " ++ show (cs)+ f2 k++f2 :: (Int -> IO ()) -> IO ()+f2 k = k 1++g1 :: Int -> IO ()+g1 n = g2 n++g2 :: Int -> IO ()+g2 n = do+ cs <- currentCallStack+ putStrLn $ "n = " ++ show n ++ " at " ++ show cs
demo/Demo/Callsite.hs view
@@ -1,13 +1,23 @@-module Demo.Callsite (- withoutDebuggable- , useDebuggable- ) where+module Demo.Callsite (Example(..), demo) where import GHC.Stack (prettyCallStack, callStack) import Debug.Provenance {-------------------------------------------------------------------------------+ Top-level+-------------------------------------------------------------------------------}++data Example =+ WithoutDebuggable+ | UseDebuggable+ deriving stock (Show)++demo :: Example -> IO ()+demo WithoutDebuggable = f1+demo UseDebuggable = g1++{------------------------------------------------------------------------------- Without the library -------------------------------------------------------------------------------} @@ -20,9 +30,6 @@ f3 :: HasCallStack => IO () f3 = putStrLn $ prettyCallStack callStack -withoutDebuggable :: IO ()-withoutDebuggable = f1- {------------------------------------------------------------------------------- Using the library -------------------------------------------------------------------------------}@@ -35,6 +42,3 @@ g3 :: HasCallStack => IO () g3 = print callSite--useDebuggable :: IO ()-useDebuggable = g1
demo/Demo/Invocation.hs view
@@ -1,18 +1,32 @@ module Demo.Invocation ( Example(..)- , withoutDebuggable- , useDebuggable+ , DebuggableExample(..)+ , demo ) where import Control.Monad import Debug.Provenance +{-------------------------------------------------------------------------------+ Top-level+-------------------------------------------------------------------------------}+ data Example =+ WithoutDebuggable+ | UseDebuggable DebuggableExample+ deriving stock (Show)++data DebuggableExample = Example1 | Example2 deriving stock (Show) +demo :: Example -> IO ()+demo WithoutDebuggable = f4+demo (UseDebuggable Example1) = g1+demo (UseDebuggable Example2) = g4+ {------------------------------------------------------------------------------- Without the library -------------------------------------------------------------------------------}@@ -25,9 +39,6 @@ -- f4 does something else .. putStrLn "f4:3" -withoutDebuggable :: IO ()-withoutDebuggable = f4- {------------------------------------------------------------------------------- Using the library -------------------------------------------------------------------------------}@@ -50,7 +61,3 @@ print =<< newInvocation -- f4 does something else .. print =<< newInvocation--useDebuggable :: Example -> IO ()-useDebuggable Example1 = g1-useDebuggable Example2 = g4
demo/Demo/NIIO.hs view
@@ -1,7 +1,4 @@-module Demo.NIIO (- withoutDebuggable- , useDebuggable- ) where+module Demo.NIIO (Example(..), demo) where import Control.Concurrent import Control.Concurrent.Async@@ -9,6 +6,19 @@ import System.IO import Debug.NonInterleavedIO qualified as NIIO++{-------------------------------------------------------------------------------+ Top-level+-------------------------------------------------------------------------------}++data Example =+ WithoutDebuggable+ | UseDebuggable+ deriving stock (Show)++demo :: Example -> IO ()+demo WithoutDebuggable = withoutDebuggable+demo UseDebuggable = useDebuggable {------------------------------------------------------------------------------- Without the library
demo/Demo/Scope.hs view
@@ -1,7 +1,4 @@-module Demo.Scope (- Example(..)- , useDebuggable- ) where+module Demo.Scope (Example(..), demo) where import Control.Concurrent import Control.Concurrent.Async@@ -10,7 +7,7 @@ import Debug.Provenance.Scope {-------------------------------------------------------------------------------- Using the library+ Top-level -------------------------------------------------------------------------------} data Example =@@ -20,6 +17,16 @@ | Example4 deriving (Show) +demo :: Example -> IO ()+demo Example1 = g4+demo Example2 = g1+demo Example3 = concurrent+demo Example4 = h1++{-------------------------------------------------------------------------------+ Using the library+-------------------------------------------------------------------------------}+ g1 :: IO () g1 = g2 @@ -52,9 +59,3 @@ concurrently_ (inheritScope tid >> g4) (inheritScope tid >> g4)--useDebuggable :: Example -> IO ()-useDebuggable Example1 = g4-useDebuggable Example2 = g1-useDebuggable Example3 = concurrent-useDebuggable Example4 = h1