packages feed

effectful-config-file 0.1.2.2 → 0.1.2.3

raw patch · 3 files changed

+42/−16 lines, 3 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

Files

CHANGELOG.md view
@@ -1,3 +1,9 @@+## [1.2.3](https://github.com/haskell-github-trust/effectful-config-file/compare/1.2.2...1.2.3) (2026-11-11)++### Bug Fixes++* avoid error span on expected not found config ([7161128](https://github.com/haskell-github-trust/effectful-config-file/commit/716112893565592f9f42d749b76db18dcaa31071))+ ## [1.2.2](https://github.com/haskell-github-trust/effectful-config-file/compare/1.2.1...1.2.2) (2026-10-31)  ## [1.2.1](https://github.com/haskell-github-trust/effectful-config-file/compare/1.2.0...1.2.1) (2026-10-31)
effectful-config-file.cabal view
@@ -5,7 +5,7 @@ -- see: https://github.com/sol/hpack  name:           effectful-config-file-version:        0.1.2.2+version:        0.1.2.3 synopsis:       Config-file effect for effectful description:    Config-file parser and utilities to use in conjunction with effectful category:       Configuration
src/Data/Config.hs view
@@ -17,7 +17,8 @@ ) where  import Control.Applicative.Combinators (choice)-import Control.Monad (void)+import Control.Exception (IOException, tryJust)+import Control.Monad (guard, void, (<=<)) import Data.ByteString.Char8 (ByteString) import qualified Data.ByteString.Char8 as B (pack) import Data.List (isPrefixOf)@@ -41,6 +42,7 @@ import System.Directory (getHomeDirectory) import System.Environment (getEnv) import System.FilePath ((</>))+import System.IO.Error (isDoesNotExistError) import Text.Megaparsec (   Parsec,   chunk,@@ -162,24 +164,42 @@     addAttribute sp "config.key" key     act sp +-- | A missing env var or file is an expected miss (callers fall back), so it+-- is tagged @config.found=false@ instead of failing the span, and rethrown+-- by 'rethrowMissing' once the span has ended.+tryMissing+  :: IOE :> es+  => Span+  -> IO b+  -> Eff es (Either IOException b)+tryMissing sp io = do+  r <- liftIO $ tryJust (\e -> e <$ guard (isDoesNotExistError e)) io+  addAttribute sp "config.found" (either (const False) (const True) r)+  pure r++rethrowMissing :: IOE :> es => Either IOException b -> Eff es b+rethrowMissing = either (liftIO . ioError) pure+ instance ConfigParse a => ConfigFetch (ConfigValue a) where   fetch (Env e) =-    withConfigSpan "env" (T.pack e) $ \_ -> do-      logDebug $ "fetching config value from env " <> T.pack e-      v <- liftIO (getEnv e)-      pure $ Literal (parse (T.pack v))+    fmap (Literal . parse . T.pack) . rethrowMissing+      <=< withConfigSpan "env" (T.pack e)+      $ \sp -> do+        logDebug $ "fetching config value from env " <> T.pack e+        tryMissing sp (getEnv e)   fetch (File fp) =-    withConfigSpan "file" (T.pack fp) $ \_ -> do-      fp' <--        if "~/" `isPrefixOf` fp-          then do-            home <- liftIO getHomeDirectory-            pure $ home </> drop 2 fp-          else pure fp+    fmap (Literal . parse . T.pack) . rethrowMissing+      <=< withConfigSpan "file" (T.pack fp)+      $ \sp -> do+        fp' <-+          if "~/" `isPrefixOf` fp+            then do+              home <- liftIO getHomeDirectory+              pure $ home </> drop 2 fp+            else pure fp -      logDebug $ "fetching config value from file " <> T.pack fp-      v <- liftIO (readFile fp')-      pure $ Literal (parse (T.pack v))+        logDebug $ "fetching config value from file " <> T.pack fp+        tryMissing sp (readFile fp')   fetch (Secret k) =     withConfigSpan "secretspec" k $ \_ -> do       logDebug $ "fetching config value from secretspec " <> k