packages feed

load-env 0.1.1 → 0.1.2

raw patch · 6 files changed

+213/−58 lines, 6 filesdep −HUnitdep ~basePVP ok

version bump matches the API change (PVP)

Dependencies removed: HUnit

Dependency ranges changed: base

API changes (from Hackage documentation)

Files

LICENSE view
@@ -1,4 +1,4 @@-Copyright (c) 2014, Pat Brisbin+Copyright (c) 2017, Pat Brisbin  All rights reserved. 
load-env.cabal view
@@ -1,42 +1,56 @@-name:                   load-env-version:                0.1.1-author:                 Pat Brisbin <pbrisbin@gmail.com>-maintainer:             Pat Brisbin <pbrisbin@gmail.com>-license:                BSD3-license-file:           LICENSE-synopsis:               Load environment variables from a file.-category:               Configuration-description:            Parse a .env file and load any declared variables into-                        the current process's environment. This allows for a-                        .env file to specify development-friendly defaults for-                        configuration values normally set in the deployment-                        environment.-cabal-version:          >= 1.10-build-type:             Simple+-- This file has been generated from package.yaml by hpack version 0.20.0.+--+-- see: https://github.com/sol/hpack+--+-- hash: 9c909afbd1a08e860e60320c5f83c51783e382789593a82de5798a86d1464c45 +name:           load-env+version:        0.1.2+synopsis:       Load environment variables from a file.+description:    Parse a .env file and load any declared variables into the current process's environment. This allows for a .env file to specify development-friendly defaults for configuration values normally set in the deployment environment.+category:       Configuration+homepage:       https://github.com/pbrisbin/load-env#readme+bug-reports:    https://github.com/pbrisbin/load-env/issues+author:         Pat Brisbin <pbrisbin@gmail.com>+maintainer:     Pat Brisbin <pbrisbin@gmail.com>+license:        BSD3+license-file:   LICENSE+build-type:     Simple+cabal-version:  >= 1.10++source-repository head+  type: git+  location: https://github.com/pbrisbin/load-env+ library-  default-language:     Haskell2010-  hs-source-dirs:       src-  ghc-options:          -Wall-  exposed-modules:      LoadEnv-                      , LoadEnv.Parse-  build-depends:        base >= 4.7.0 && < 5-                      , directory-                      , parsec+  hs-source-dirs:+      src+  ghc-options: -Wall+  build-depends:+      base >=4.8.0 && <5+    , directory+    , parsec+  exposed-modules:+      LoadEnv+      LoadEnv.Parse+  other-modules:+      Paths_load_env+  default-language: Haskell2010  test-suite spec-  type:                 exitcode-stdio-1.0-  default-language:     Haskell2010-  hs-source-dirs:       test-  ghc-options:          -Wall-  main-is:              Spec.hs-  build-depends:        base-                      , load-env-                      , directory-                      , hspec-                      , HUnit-                      , parsec--source-repository head-  type:                 git-  location:             https://github.com/pbrisbin/load-env+  type: exitcode-stdio-1.0+  main-is: Spec.hs+  hs-source-dirs:+      test+  ghc-options: -Wall+  build-depends:+      base >=4.8.0 && <5+    , directory+    , hspec+    , load-env+    , parsec+  other-modules:+      LoadEnv.ParseSpec+      LoadEnvSpec+      Paths_load_env+  default-language: Haskell2010
src/LoadEnv.hs view
@@ -5,11 +5,10 @@   import Control.Monad (when)+import LoadEnv.Parse import System.Directory (doesFileExist) import System.Environment (setEnv) import Text.Parsec.String (parseFromFile)--import LoadEnv.Parse  -- | --
src/LoadEnv/Parse.hs view
@@ -1,4 +1,3 @@-{-# LANGUAGE CPP #-} module LoadEnv.Parse     ( Environment     , Variable@@ -6,13 +5,8 @@     , parseVariable     ) where -#if __GLASGOW_HASKELL__ < 710-import Control.Applicative ((<$>))-#endif- import Control.Monad (void) import Data.Maybe (catMaybes)- import Text.Parsec import Text.Parsec.String @@ -26,25 +20,22 @@ parseLine = possibly parseVariable  possibly :: Parser a -> Parser (Maybe a)-possibly p = try (fmap Just p) <|> ignored+possibly p = try (Just <$> p) <|> ignored    where-    ignored = do-        void $ manyTill anyToken newline-        return Nothing+    ignored = Nothing <$ manyTill anyToken newline  parseVariable :: Parser Variable parseVariable = do     optional $ between spaces spaces $ string "export"      i <- identifier-    void $ char '='+    v <- char '=' *> value -    v <- value     void $ many $ oneOf " \t"-    void $ newline+    void newline -    return (i, v)+    pure (i, v)  -- Environment variable names used by the utilities in the Shell and Utilities -- volume of IEEE Std 1003.1-2001 consist solely of uppercase letters, digits,@@ -58,13 +49,13 @@     x <- upper <|> underscore     ys <- many $ upper <|> digit <|> underscore -    return (x:ys)+    pure (x:ys)    where     underscore = char '_'  value :: Parser String-value = quotedValue <|> unquotedValue <|> return ""+value = quotedValue <|> unquotedValue <|> pure ""  quotedValue :: Parser String quotedValue = do@@ -76,4 +67,4 @@ unquotedValue = many1 $ try (escaped ' ') <|> noneOf "\"' \n"  escaped :: Char -> Parser Char-escaped c = string ("\\" ++ [c]) >> return c+escaped c = c <$ string ("\\" ++ [c])
+ test/LoadEnv/ParseSpec.hs view
@@ -0,0 +1,113 @@+module LoadEnv.ParseSpec+    ( spec+    ) where++import LoadEnv.Parse+import Test.Hspec+import Text.Parsec (parse)++spec :: Spec+spec = do+    describe "parseEnvironment" $ do+        it "parses variable declarations among comments and blank lines" $ do+            let env = unlines+                    [ "# An environment file"+                    , "FOO=bar"+                    , "BAZ=\"bat\""+                    , "BAT=\"multi-"+                    , "pass"+                    , "\""+                    , ""+                    , "# vim ft:sh:"+                    ]++            parse parseEnvironment "" env `shouldBe` Right+                [ ("FOO", "bar")+                , ("BAZ", "bat")+                , ("BAT", "multi-\npass\n")+                ]++        it "parses an empty file into an empty list of variables" $ do+            parse parseEnvironment "" "" `shouldBe` Right []+++    describe "parseVariable" $ do+        it "reads unquoted variables" $+            parse parseVariable "" "FOO=bar\n" `shouldBe` Right ("FOO", "bar")++        it "reads quoted variables" $ do+            parse parseVariable "" "FOO=\"bar\"\n"+                `shouldBe` Right ("FOO", "bar")+            parse parseVariable "" "FOO='bar'\n"+                `shouldBe` Right ("FOO", "bar")++        it "allows newlines in quoted variables" $ do+            parse parseVariable "" "FOO=\"foo\nbar\"\n"+                `shouldBe` Right ("FOO", "foo\nbar")++        it "handles empty values" $+            parse parseVariable "" "FOO=\n" `shouldBe` Right ("FOO", "")++        it "handles empty quoted values" $ do+            parse parseVariable "" "FOO=\"\"\n" `shouldBe` Right ("FOO", "")+            parse parseVariable "" "FOO=''\n" `shouldBe` Right ("FOO", "")++        it "handles underscored variables" $+            parse parseVariable "" "FOO_BAR=baz\n"+                `shouldBe` Right ("FOO_BAR", "baz")++        it "treats leading spaces as invalid" $+            parse parseVariable "" "  FOO=bar\n"+                `shouldContainError` "unexpected \"F\""++        it "treats spaces around equals as invalid" $+            parse parseVariable "" "FOO = bar\n"+                `shouldContainError` "unexpected \" \""++        it "treats unquoted spaces as invalid" $+            parse parseVariable "" "FOO=bar baz\n"+                `shouldContainError` "unexpected \"b\""++        it "treats unbalanced quotes as invalid" $ do+            parse parseVariable "" "FOO=\"bar\n"+                `shouldContainError` "unexpected end of input"+            parse parseVariable "" "FOO='bar\n"+                `shouldContainError` "unexpected end of input"+            parse parseVariable "" "FOO=bar\"\n"+                `shouldContainError` "unexpected \"\\\"\""+            parse parseVariable "" "FOO=bar'\n"+                `shouldContainError` "unexpected \"\'\""++        it "handles escaped quotes" $ do+            parse parseVariable "" "FOO=\"bar\\\"baz\"\n"+                `shouldBe` Right ("FOO", "bar\"baz")+            parse parseVariable "" "FOO='bar\\'baz'\n"+                `shouldBe` Right ("FOO", "bar'baz")++        it "handles escaped spaces" $+            parse parseVariable "" "FOO=bar\\ baz\n"+                `shouldBe` Right ("FOO", "bar baz")++        it "discards any lines using `export'" $+            parse parseVariable "" "export FOO=bar\n"+                `shouldBe` Right ("FOO", "bar")++        it "requires valid environment variable identifies" $ do+            parse parseVariable "" "S3_KEY=abc123\n"+                `shouldBe` Right ("S3_KEY", "abc123")+            parse parseVariable "" "_S3_KEY=abc123\n"+                `shouldBe` Right ("_S3_KEY", "abc123")++            parse parseVariable "" "S3~KEY=abc123\n"+                `shouldContainError` "unexpected \"~\""+            parse parseVariable "" "S3-KEY=abc123\n"+                `shouldContainError` "unexpected \"-\""+            parse parseVariable "" "S3_key=abc123\n"+                `shouldContainError` "unexpected \"k\""+            parse parseVariable "" "3_KEY=abc123\n"+                `shouldContainError` "unexpected \"3\""++shouldContainError :: Show a => Either a b -> String -> Expectation+v `shouldContainError` msg = either+    (\e -> show e `shouldContain` msg)+    (\_ -> expectationFailure "Expected no parse") v
+ test/LoadEnvSpec.hs view
@@ -0,0 +1,38 @@+module LoadEnvSpec+    ( spec+    ) where++import Control.Monad (when)+import LoadEnv+import System.Directory (doesFileExist, removeFile)+import System.Environment (lookupEnv)+import Test.Hspec++spec :: Spec+spec = after_ cleanup $+    describe "loadEnv" $ do+        it "loads environment variables from ./.env if present" $ do+            writeFile envFile $ unlines+                [ "FOO=\"bar\""+                , "BAZ=\"bat\""+                ]++            loadEnvFrom envFile++            mbar <- lookupEnv "FOO"+            mbat <- lookupEnv "BAZ"+            mbar `shouldBe` Just "bar"+            mbat `shouldBe` Just "bat"++        it "does not fail if the file is not present" $ do+            loadEnvFrom "i-do-not-exist"++            return ()++cleanup :: IO ()+cleanup = do+    e <- doesFileExist envFile+    when e $ removeFile envFile++envFile :: FilePath+envFile = "/tmp/load-env-test-file"