packages feed

freckle-env 0.0.0.0 → 0.0.1.1

raw patch · 5 files changed

+96/−14 lines, 5 filesdep +dotenvdep +filepathdep +unliftiodep −reludePVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies added: dotenv, filepath, unliftio

Dependencies removed: relude

API changes (from Hackage documentation)

+ Freckle.App.Dotenv: load :: IO ()
+ Freckle.App.Dotenv: loadFile :: FilePath -> IO ()
+ Freckle.App.Dotenv: loadTest :: IO ()
+ Freckle.App.Env: widthMax :: Int -> Info e -> Info e
- Freckle.App.Env: class () => AsEmpty e
+ Freckle.App.Env: class AsEmpty e
- Freckle.App.Env: class () => AsUnread e
+ Freckle.App.Env: class AsUnread e
- Freckle.App.Env: class () => AsUnset e
+ Freckle.App.Env: class AsUnset e
- Freckle.App.Env: class () => HasHelp (t :: Type -> Type)
+ Freckle.App.Env: class HasHelp (t :: Type -> Type)
- Freckle.App.Env: data () => Error
+ Freckle.App.Env: data Error
- Freckle.App.Env: data () => Flag a
+ Freckle.App.Env: data Flag a
- Freckle.App.Env: data () => Info e
+ Freckle.App.Env: data Info e
- Freckle.App.Env: data () => Mod (t :: Type -> Type) a
+ Freckle.App.Env: data Mod (t :: Type -> Type) a
- Freckle.App.Env: data () => Parser e a
+ Freckle.App.Env: data Parser e a
- Freckle.App.Env: data () => Var a
+ Freckle.App.Env: data Var a
- Freckle.App.Env: helpDoc :: Parser e a -> String
+ Freckle.App.Env: helpDoc :: Int -> Parser e a -> String

Files

CHANGELOG.md view
@@ -1,4 +1,12 @@-## [_Unreleased_](https://github.com/freckle/freckle-app/compare/freckle-env-v0.0.0.0...main)+## [_Unreleased_](https://github.com/freckle/freckle-app/compare/freckle-env-v0.0.1.1...main)++## [v0.0.1.1](https://github.com/freckle/freckle-app/compare/freckle-env-v0.0.1.0...freckle-env-v0.0.1.1)++Drop `relude` dependency++## [v0.0.1.0](https://github.com/freckle/freckle-app/compare/freckle-env-v0.0.0.0...freckle-env-v0.0.1.0)++Added module `Freckle.App.Dotenv` (moved from `freckle-app-1.19.0.0`).  ## [v0.0.0.0](https://github.com/freckle/freckle-app/tree/freckle-env-v0.0.0.0/freckle-env) 
freckle-env.cabal view
@@ -1,6 +1,6 @@ cabal-version:      1.18 name:               freckle-env-version:            0.0.0.0+version:            0.0.1.1 license:            MIT license-file:       LICENSE maintainer:         Freckle Education@@ -20,7 +20,10 @@     location: https://github.com/freckle/freckle-app  library-    exposed-modules:    Freckle.App.Env+    exposed-modules:+        Freckle.App.Dotenv+        Freckle.App.Env+     hs-source-dirs:     library     other-modules:      Paths_freckle_env     default-language:   GHC2021@@ -39,11 +42,13 @@      build-depends:         base >=4.16.4.0 && <5,+        dotenv >=0.10.0.0,         envparse >=0.5.0,         errors >=2.3.0,-        relude >=1.1.0.0,+        filepath >=1.4.2.2,         text >=1.2.5.0,-        time >=1.11.1.1+        time >=1.11.1.1,+        unliftio >=0.2.25.0      if impl(ghc >=9.8)         ghc-options:
+ library/Freckle/App/Dotenv.hs view
@@ -0,0 +1,65 @@+-- | Conventional @.env@ handling+module Freckle.App.Dotenv+  ( load+  , loadTest+  , loadFile+  ) where++import Prelude++import Configuration.Dotenv qualified as Dotenv+import Control.Monad ((<=<))+import Data.Foldable (traverse_)+import Data.Functor (void)+import System.FilePath (takeDirectory, (</>))+import UnliftIO.Directory (doesFileExist, getCurrentDirectory)++-- | Call 'loadFile' with @.env@+load :: IO ()+load = loadFile ".env"++-- | Call 'loadFile' with @.env.test@+loadTest :: IO ()+loadTest = loadFile ".env.test"++-- | An opinionated 'Configuration.Dotenv.loadFile'+--+-- Additional behaviors:+--+-- 1. Attempt to locate the file in parent directories too+--+--    We, sadly, have a monorepository. So we need to locate a @.env@ file in+--    parent directories when running tests in sub-directories.+--+-- 2. Silently ignore no file found+--+--    Since this is used by 'Freckle.App.Test.withApp', which we aim to use in+--    every non-trivial project, we can't fail in projects that don't need or+--    have a @.env(.test)@ file (such as this one!).+--+-- 3. Use the @.env.example@ feature, but only if one exists alongside+loadFile :: FilePath -> IO ()+loadFile = traverse_ go <=< locateInParents+ where+  go path = do+    let examplePath = takeDirectory path </> ".env.example"+    exampleExists <- doesFileExist examplePath++    void $+      Dotenv.loadFile $+        Dotenv.defaultConfig+          { Dotenv.configPath = [path]+          , Dotenv.configExamplePath = [examplePath | exampleExists]+          }++locateInParents :: FilePath -> IO (Maybe FilePath)+locateInParents path = go =<< getCurrentDirectory+ where+  go cwd = do+    let absPath = cwd </> path++    exists <- doesFileExist absPath++    if exists+      then pure $ Just absPath+      else if cwd == "/" then pure Nothing else go $ takeDirectory cwd
library/Freckle/App/Env.hs view
@@ -35,10 +35,12 @@   , timeout   ) where -import Relude+import Prelude  import Control.Error.Util (note)+import Data.Bifunctor (first, second) import Data.Char (isDigit)+import Data.Text (Text) import Data.Text qualified as T import Data.Time (UTCTime, defaultTimeLocale, parseTimeM) import Env hiding (flag)@@ -94,9 +96,9 @@ -- Left [("TIME",UnreadError "unable to parse time as %Y-%m-%d: \"10:00PM\"")] time :: String -> Env.Reader Error UTCTime time fmt =-  eitherReader-    $ note ("unable to parse time as " <> fmt)-    . parseTimeM True defaultTimeLocale fmt+  eitherReader $+    note ("unable to parse time as " <> fmt)+      . parseTimeM True defaultTimeLocale fmt  -- | Read key-value pairs --@@ -117,11 +119,11 @@  keyValue :: Char -> Env.Reader Error (Text, Text) keyValue c =-  eitherReader $ go . second (T.drop 1) . T.breakOn (T.singleton c) . toText+  eitherReader $ go . second (T.drop 1) . T.breakOn (T.singleton c) . T.pack  where   go = \case-    (k, v) | T.null v -> Left $ "Key " <> toString k <> " has no value"-    (k, v) | T.null k -> Left $ "Value " <> toString v <> " has no key"+    (k, v) | T.null v -> Left $ "Key " <> T.unpack k <> " has no value"+    (k, v) | T.null k -> Left $ "Value " <> T.unpack v <> " has no key"     (k, v) -> Right (k, v)  -- | Use 'splitOn' then call the given 'Reader' on each element
package.yaml view
@@ -1,5 +1,5 @@ name: freckle-env-version: 0.0.0.0+version: 0.0.1.1 maintainer: Freckle Education category: Environment, System github: freckle/freckle-app@@ -54,11 +54,13 @@ library:   source-dirs: library   dependencies:+    - dotenv     - envparse     - errors-    - relude+    - filepath     - text     - time+    - unliftio  tests:   doctest: