From eb680828b8baa474fa7b00e09dc2236f50523643 Mon Sep 17 00:00:00 2001 From: patrick brisbin Date: Wed, 10 Sep 2014 15:44:39 -0400 Subject: [PATCH 1/9] Fix typo in haddocks --- src/LoadEnv.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/LoadEnv.hs b/src/LoadEnv.hs index 5eaed28..927673e 100644 --- a/src/LoadEnv.hs +++ b/src/LoadEnv.hs @@ -29,7 +29,7 @@ import LoadEnv.Parse -- -- If you wish to specify your own file, use @'loadEnvFrom'@. If you wish to -- pass your own string or work with the parse result directly, use the --- lower-level functions available in @"System.Env.Parse"@. +-- lower-level functions available in @"LoadEnv.Parse"@. -- loadEnv :: IO () loadEnv = loadEnvFrom ".env" From bef4212020102f932c4ce1370bfe3718708cfd18 Mon Sep 17 00:00:00 2001 From: patrick brisbin Date: Wed, 10 Sep 2014 15:44:51 -0400 Subject: [PATCH 2/9] Version bump --- load-env.cabal | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/load-env.cabal b/load-env.cabal index ba93283..29fecee 100644 --- a/load-env.cabal +++ b/load-env.cabal @@ -1,5 +1,5 @@ Name: load-env -Version: 0.0.4 +Version: 0.0.5 Author: Pat Brisbin Maintainer: Pat Brisbin License: BSD3 From b584c9980b79688fcddf32b2daa2aa2a1a6588fe Mon Sep 17 00:00:00 2001 From: patrick brisbin Date: Wed, 3 Dec 2014 19:31:23 -0500 Subject: [PATCH 3/9] HSpec api change: use after_ --- test/LoadEnvSpec.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/LoadEnvSpec.hs b/test/LoadEnvSpec.hs index 6005a6a..3db12d1 100644 --- a/test/LoadEnvSpec.hs +++ b/test/LoadEnvSpec.hs @@ -11,7 +11,7 @@ main :: IO () main = hspec spec spec :: Spec -spec = after cleanup $ do +spec = after_ cleanup $ do describe "loadEnv" $ do it "loads environment variables from ./.env if present" $ do writeFile envFile $ unlines From 3c74a4cb1240d0cb7e2122b886f6f2427da21b36 Mon Sep 17 00:00:00 2001 From: patrick brisbin Date: Wed, 3 Dec 2014 19:38:29 -0500 Subject: [PATCH 4/9] Use void and newline --- src/LoadEnv/Parse.hs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/LoadEnv/Parse.hs b/src/LoadEnv/Parse.hs index 89c5b59..d03973f 100644 --- a/src/LoadEnv/Parse.hs +++ b/src/LoadEnv/Parse.hs @@ -6,6 +6,7 @@ module LoadEnv.Parse ) where import Control.Applicative ((<$>), (<*>)) +import Control.Monad (void) import Data.Maybe (catMaybes) import Text.Parsec @@ -25,14 +26,14 @@ ignoreLine = (commentLine <|> blankLine) >> return Nothing commentLine :: Parser () commentLine = do - _ <- spaces - _ <- char '#' - _ <- manyTill anyToken (char '\n') + void spaces + void $ char '#' + void $ manyTill anyToken newline return () blankLine :: Parser () -blankLine = many1 space >> return () +blankLine = void $ many1 space parseVariable :: Parser Variable parseVariable = (,) <$> identifier <*> value @@ -42,15 +43,15 @@ identifier = do optional $ between spaces spaces $ string "export" i <- many1 $ letter <|> char '_' - _ <- char '=' + void $ char '=' return i value :: Parser String value = do v <- quotedValue <|> unquotedValue <|> return "" - _ <- many $ oneOf " \t" - _ <- char '\n' + void $ many $ oneOf " \t" + void newline return v From 51f54daee05990787ca616cb9ee7cb09eebc373f Mon Sep 17 00:00:00 2001 From: patrick brisbin Date: Wed, 3 Dec 2014 19:40:22 -0500 Subject: [PATCH 5/9] hlint --- README.md | 2 +- src/LoadEnv.hs | 4 ++-- src/LoadEnv/Parse.hs | 6 +++--- test/LoadEnv/ParseSpec.hs | 18 +++++++++--------- test/LoadEnvSpec.hs | 2 +- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 890ee90..b8b3acb 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ main :: IO () main = do loadEnv - putStrLn . show =<< lookupEnv "FOO" + print =<< lookupEnv "FOO" -- % cat .env -- FOO=bar diff --git a/src/LoadEnv.hs b/src/LoadEnv.hs index 927673e..105520f 100644 --- a/src/LoadEnv.hs +++ b/src/LoadEnv.hs @@ -38,5 +38,5 @@ loadEnvFrom :: FilePath -> IO () loadEnvFrom fp = do e <- doesFileExist fp - when e $ parseFromFile parseEnvironment fp >>= either - (putStrLn . show) (mapM_ $ uncurry setEnv) + when e $ parseFromFile parseEnvironment fp >>= + either print (mapM_ $ uncurry setEnv) diff --git a/src/LoadEnv/Parse.hs b/src/LoadEnv/Parse.hs index d03973f..74c4066 100644 --- a/src/LoadEnv/Parse.hs +++ b/src/LoadEnv/Parse.hs @@ -16,10 +16,10 @@ type Environment = [Variable] type Variable = (String, String) parseEnvironment :: Parser Environment -parseEnvironment = fmap catMaybes $ many1 parseLine +parseEnvironment = catMaybes <$> many1 parseLine parseLine :: Parser (Maybe Variable) -parseLine = try (fmap Just $ parseVariable) <|> ignoreLine +parseLine = try (fmap Just parseVariable) <|> ignoreLine ignoreLine :: Parser (Maybe Variable) ignoreLine = (commentLine <|> blankLine) >> return Nothing @@ -62,7 +62,7 @@ quotedValue = do manyTill (try (escaped q) <|> anyToken) (char q) unquotedValue :: Parser String -unquotedValue = many1 $ try (escaped ' ') <|> (noneOf "\"' \n") +unquotedValue = many1 $ try (escaped ' ') <|> noneOf "\"' \n" escaped :: Char -> Parser Char escaped c = string ("\\" ++ [c]) >> return c diff --git a/test/LoadEnv/ParseSpec.hs b/test/LoadEnv/ParseSpec.hs index 78c04c5..2bfc3ee 100644 --- a/test/LoadEnv/ParseSpec.hs +++ b/test/LoadEnv/ParseSpec.hs @@ -11,7 +11,7 @@ main = hspec spec spec :: Spec spec = do - describe "parseEnvironment" $ do + describe "parseEnvironment" $ it "parses variable declarations among comments and blank lines" $ do let input = unlines [ "# An environment file" @@ -29,30 +29,30 @@ spec = do Right v -> v `shouldBe` expected describe "parseVariable" $ do - it "reads unquoted variables" $ do + it "reads unquoted variables" $ "FOO=bar\n" `shouldParseTo` ("FOO", "bar") it "reads quoted variables" $ do "FOO=\"bar\"\n" `shouldParseTo` ("FOO", "bar") "FOO='bar'\n" `shouldParseTo` ("FOO", "bar") - it "handles empty values" $ do + it "handles empty values" $ "FOO=\n" `shouldParseTo` ("FOO", "") it "handles empty quoted values" $ do "FOO=\"\"\n" `shouldParseTo` ("FOO", "") "FOO=''\n" `shouldParseTo` ("FOO", "") - it "handles underscored variables" $ do + it "handles underscored variables" $ "FOO_BAR=baz\n" `shouldParseTo` ("FOO_BAR", "baz") - it "treats leading spaces as invalid" $ do + it "treats leading spaces as invalid" $ expectFailedParse " FOO=bar\n" - it "treats spaces around equals as invalid" $ do + it "treats spaces around equals as invalid" $ expectFailedParse "FOO = bar\n" - it "treats unquoted spaces as invalid" $ do + it "treats unquoted spaces as invalid" $ expectFailedParse "FOO=bar baz\n" it "treats unbalanced quotes as invalid" $ do @@ -65,10 +65,10 @@ spec = do "FOO=\"bar\\\"baz\"\n" `shouldParseTo` ("FOO", "bar\"baz") "FOO='bar\\'baz'\n" `shouldParseTo` ("FOO", "bar'baz") - it "handles escaped spaces" $ do + it "handles escaped spaces" $ "FOO=bar\\ baz\n" `shouldParseTo` ("FOO", "bar baz") - it "discards any lines using `export'" $ do + it "discards any lines using `export'" $ "export FOO=bar\n" `shouldParseTo` ("FOO", "bar") shouldParseTo :: String -> Variable -> Expectation diff --git a/test/LoadEnvSpec.hs b/test/LoadEnvSpec.hs index 3db12d1..df9a43e 100644 --- a/test/LoadEnvSpec.hs +++ b/test/LoadEnvSpec.hs @@ -11,7 +11,7 @@ main :: IO () main = hspec spec spec :: Spec -spec = after_ cleanup $ do +spec = after_ cleanup $ describe "loadEnv" $ do it "loads environment variables from ./.env if present" $ do writeFile envFile $ unlines From 2b8e2c82f15a59d32c8dcaf8f6f6d9c2ea78bbda Mon Sep 17 00:00:00 2001 From: patrick brisbin Date: Wed, 3 Dec 2014 19:43:47 -0500 Subject: [PATCH 6/9] Don't fail on an empty file --- src/LoadEnv/Parse.hs | 2 +- test/LoadEnv/ParseSpec.hs | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/LoadEnv/Parse.hs b/src/LoadEnv/Parse.hs index 74c4066..a6284d9 100644 --- a/src/LoadEnv/Parse.hs +++ b/src/LoadEnv/Parse.hs @@ -16,7 +16,7 @@ type Environment = [Variable] type Variable = (String, String) parseEnvironment :: Parser Environment -parseEnvironment = catMaybes <$> many1 parseLine +parseEnvironment = catMaybes <$> many parseLine parseLine :: Parser (Maybe Variable) parseLine = try (fmap Just parseVariable) <|> ignoreLine diff --git a/test/LoadEnv/ParseSpec.hs b/test/LoadEnv/ParseSpec.hs index 2bfc3ee..8f0dd63 100644 --- a/test/LoadEnv/ParseSpec.hs +++ b/test/LoadEnv/ParseSpec.hs @@ -11,7 +11,7 @@ main = hspec spec spec :: Spec spec = do - describe "parseEnvironment" $ + describe "parseEnvironment" $ do it "parses variable declarations among comments and blank lines" $ do let input = unlines [ "# An environment file" @@ -28,6 +28,13 @@ spec = do Left err -> assertFailure $ "Parse failure: " ++ show err Right v -> v `shouldBe` expected + it "parses an empty file into an empty list of variables" $ do + let result = parse parseEnvironment "" "" + + case result of + Left err -> assertFailure $ "Parse failure: " ++ show err + Right v -> v `shouldBe` [] + describe "parseVariable" $ do it "reads unquoted variables" $ "FOO=bar\n" `shouldParseTo` ("FOO", "bar") From b14091a00a96489df166bf4333edf7593fecd2b8 Mon Sep 17 00:00:00 2001 From: patrick brisbin Date: Wed, 3 Dec 2014 19:56:36 -0500 Subject: [PATCH 7/9] Simplify parsing by ignoring failed lines - Move newline handling out of variable parser --- src/LoadEnv.hs | 8 ++++---- src/LoadEnv/Parse.hs | 27 ++++++++++++--------------- 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/src/LoadEnv.hs b/src/LoadEnv.hs index 105520f..68a40e6 100644 --- a/src/LoadEnv.hs +++ b/src/LoadEnv.hs @@ -22,10 +22,10 @@ import LoadEnv.Parse -- > FOO='bar' -- -- Declarations may optionally be preceded by @export@, which will be ignored. --- Lines beginning with @#@ and blank lines are ignored. Trailing whitespace is --- ignored. Quotes inside quoted values or spaces in unquoted values must be --- escaped with a backlash. All else will result in a parse error being printed --- to @stdout@. +-- Trailing whitespace is ignored. Quotes inside quoted values or spaces in +-- unquoted values must be escaped with a backlash. +-- +-- Invalid lines are silently ignored. -- -- If you wish to specify your own file, use @'loadEnvFrom'@. If you wish to -- pass your own string or work with the parse result directly, use the diff --git a/src/LoadEnv/Parse.hs b/src/LoadEnv/Parse.hs index a6284d9..d947d6d 100644 --- a/src/LoadEnv/Parse.hs +++ b/src/LoadEnv/Parse.hs @@ -19,24 +19,21 @@ parseEnvironment :: Parser Environment parseEnvironment = catMaybes <$> many parseLine parseLine :: Parser (Maybe Variable) -parseLine = try (fmap Just parseVariable) <|> ignoreLine +parseLine = possibly parseVariable -ignoreLine :: Parser (Maybe Variable) -ignoreLine = (commentLine <|> blankLine) >> return Nothing +possibly :: Parser a -> Parser (Maybe a) +possibly p = try (fmap Just p) <|> ignored -commentLine :: Parser () -commentLine = do - void spaces - void $ char '#' - void $ manyTill anyToken newline - - return () - -blankLine :: Parser () -blankLine = void $ many1 space + where + ignored = do + void $ manyTill anyToken newline + return Nothing parseVariable :: Parser Variable -parseVariable = (,) <$> identifier <*> value +parseVariable = do + v <- (,) <$> identifier <*> value + void $ newline + return v identifier :: Parser String identifier = do @@ -50,8 +47,8 @@ identifier = do value :: Parser String value = do v <- quotedValue <|> unquotedValue <|> return "" + void $ many $ oneOf " \t" - void newline return v From d84db9442fbceb91927d15da667af400a023f7c7 Mon Sep 17 00:00:00 2001 From: patrick brisbin Date: Wed, 3 Dec 2014 20:04:15 -0500 Subject: [PATCH 8/9] Better layers of abstraction - identifier/value are only concerned with that - parseVariable handles the equals, whitespace and newline --- src/LoadEnv/Parse.hs | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/src/LoadEnv/Parse.hs b/src/LoadEnv/Parse.hs index d947d6d..97472b4 100644 --- a/src/LoadEnv/Parse.hs +++ b/src/LoadEnv/Parse.hs @@ -5,7 +5,7 @@ module LoadEnv.Parse , parseVariable ) where -import Control.Applicative ((<$>), (<*>)) +import Control.Applicative ((<$>)) import Control.Monad (void) import Data.Maybe (catMaybes) @@ -31,26 +31,22 @@ possibly p = try (fmap Just p) <|> ignored parseVariable :: Parser Variable parseVariable = do - v <- (,) <$> identifier <*> value - void $ newline - return v - -identifier :: Parser String -identifier = do optional $ between spaces spaces $ string "export" - i <- many1 $ letter <|> char '_' + i <- identifier void $ char '=' - return i + v <- value + void $ many $ oneOf " \t" + void $ newline -value :: Parser String -value = do - v <- quotedValue <|> unquotedValue <|> return "" + return (i, v) - void $ many $ oneOf " \t" +identifier :: Parser String +identifier = many1 $ letter <|> char '_' - return v +value :: Parser String +value = quotedValue <|> unquotedValue <|> return "" quotedValue :: Parser String quotedValue = do From 7a07453b43d5fd302c4ba2ccdd3b4d8d18086030 Mon Sep 17 00:00:00 2001 From: patrick brisbin Date: Wed, 3 Dec 2014 20:04:56 -0500 Subject: [PATCH 9/9] Version bump --- load-env.cabal | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/load-env.cabal b/load-env.cabal index 29fecee..a89efbd 100644 --- a/load-env.cabal +++ b/load-env.cabal @@ -1,5 +1,5 @@ Name: load-env -Version: 0.0.5 +Version: 0.1.0 Author: Pat Brisbin Maintainer: Pat Brisbin License: BSD3