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 +6/−0
- effectful-config-file.cabal +1/−1
- src/Data/Config.hs +35/−15
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