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 +9/−1
- freckle-env.cabal +9/−4
- library/Freckle/App/Dotenv.hs +65/−0
- library/Freckle/App/Env.hs +9/−7
- package.yaml +4/−2
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: