dotenv 0.9.0.2 → 0.9.0.3
raw patch · 7 files changed
+70/−46 lines, 7 filesdep +shellwordsPVP ok
version bump matches the API change (PVP)
Dependencies added: shellwords
API changes (from Hackage documentation)
Files
- CHANGELOG.md +4/−0
- LICENSE +18/−17
- README.md +11/−11
- dotenv.cabal +3/−1
- spec/Configuration/Dotenv/ParseSpec.hs +21/−6
- src/Configuration/Dotenv/Parse.hs +7/−5
- src/Configuration/Dotenv/ParsedVariable.hs +6/−6
CHANGELOG.md view
@@ -1,4 +1,8 @@ ## MASTER+## Dotenv 0.9.0.3+### Added+* Parse multi-word command interpolations (Kudos to @pbrisbin)+ ## Dotenv 0.9.0.2 ### Added * Support for GHC = 9.0
LICENSE view
@@ -1,20 +1,21 @@-Copyright (c) 2015-2020 Justin Leitgeb+MIT License -Permission is hereby granted, free of charge, to any person obtaining-a copy of this software and associated documentation files (the-"Software"), to deal in the Software without restriction, including-without limitation the rights to use, copy, modify, merge, publish,-distribute, sublicense, and/or sell copies of the Software, and to-permit persons to whom the Software is furnished to do so, subject to-the following conditions:+Copyright (c) 2022 Stack Builders Inc. -The above copyright notice and this permission notice shall be included-in all copies or substantial portions of the Software.+Permission is hereby granted, free of charge, to any person obtaining a copy+of this software and associated documentation files (the "Software"), to deal+in the Software without restriction, including without limitation the rights+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+copies of the Software, and to permit persons to whom the Software is+furnished to do so, subject to the following conditions: -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.-IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.+The above copyright notice and this permission notice shall be included in all+copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+SOFTWARE.
README.md view
@@ -17,7 +17,7 @@ files. This library loads configuration to environment variables for programs written in Haskell. -## Installation+## Install In most cases you will just add `dotenv` to your cabal file. You can also install the library and executable by invoking `stack install dotenv` or@@ -80,7 +80,7 @@ postgres://myusername@localhost/database ``` -## Configuration+### Configuration The first argument to `loadFile` specifies the configuration. You cans use `defaultConfig` which parses the `.env` file in your current directory and@@ -99,7 +99,7 @@ (e.g `[".env.example", ".tokens.example", ".public_keys.example"]`). If you don't need this functionality you can set `configExamplePath` to an empty list. -## Advanced Dotenv File Syntax+### Advanced Dotenv File Syntax You can add comments to your Dotenv file, on separate lines or after values. Values can be wrapped in single or double quotes. Multi-line@@ -109,7 +109,7 @@ The [spec file](spec/Configuration/Dotenv/ParseSpec.hs) is the best place to understand the nuances of Dotenv file parsing. -## Command-Line Usage+### Command-Line Usage You can call dotenv from the command line in order to load settings from one or more dotenv file before invoking an executable:@@ -172,14 +172,14 @@ of `myprogram` above you can see what the environment will look like after evaluating multiple Dotenv files. -## Author--Justin Leitgeb- ## License -MIT+MIT, see [the LICENSE file](LICENSE). -## Copyright+## Contributing -(C) 2015-2020 [Stack Builders Inc.](http://www.stackbuilders.com)+Do you want to contribute to this project? Please take a look at our [contributing guideline](/docs/CONTRIBUTING.md) to know how you can help us build it.++---+<img src="https://www.stackbuilders.com/media/images/Sb-supports.original.png" alt="Stack Builders" width="50%"></img>+[Check out our libraries](https://github.com/stackbuilders/) | [Join our team](https://www.stackbuilders.com/join-us/)
dotenv.cabal view
@@ -1,5 +1,5 @@ name: dotenv-version: 0.9.0.2+version: 0.9.0.3 synopsis: Loads environment variables from dotenv files homepage: https://github.com/stackbuilders/dotenv-hs description:@@ -95,6 +95,7 @@ , megaparsec >= 7.0.1 && < 10.0 , containers , process >= 1.6.3.0 && < 1.7+ , shellwords >= 0.1.3.0 , text , exceptions >= 0.8 && < 0.11 @@ -128,6 +129,7 @@ , megaparsec , hspec , process+ , shellwords , text , exceptions >= 0.8 && < 0.11 , hspec-megaparsec >= 2.0 && < 3.0
spec/Configuration/Dotenv/ParseSpec.hs view
@@ -7,7 +7,7 @@ VarValue(..), VarFragment(..)) import Data.Void (Void)-import Test.Hspec (it, describe, Spec, hspec)+import Test.Hspec (it, context, describe, Spec, hspec) import Test.Hspec.Megaparsec (shouldParse, shouldFailOn, shouldSucceedOn) import Text.Megaparsec (ParseErrorBundle, parse) @@ -142,11 +142,26 @@ it "doesn't allow more configuration options after a quoted value" $ parseConfig `shouldFailOn` "foo='bar'baz='buz'" - it "parses a command $(command)" $ do- parseConfig "FOO=$(command)"- `shouldParse` [ParsedVariable "FOO" (Unquoted [CommandInterpolation "command"])]- parseConfig "FOO=asdf_$(command)"- `shouldParse` [ParsedVariable "FOO" (Unquoted [VarLiteral "asdf_", CommandInterpolation "command"])]+ context "$(command) interpolation" $ do+ it "parses a simple command" $ do+ parseConfig "FOO=$(command)"+ `shouldParse` [ParsedVariable "FOO" (Unquoted [CommandInterpolation "command" []])]++ it "parses a command anywhere in the value" $ do+ parseConfig "FOO=asdf_$(command)"+ `shouldParse` [ParsedVariable "FOO" (Unquoted [VarLiteral "asdf_", CommandInterpolation "command" []])]++ it "parses a command with arguments" $ do+ parseConfig "FOO=$(foo-bar arg1 arg2)"+ `shouldParse` [ParsedVariable "FOO" (Unquoted [CommandInterpolation "foo-bar" ["arg1", "arg2"]])]++ it "parses a command with quoted arguments" $ do+ parseConfig "FOO=$(bin/foo \"arg 1\" arg2)"+ `shouldParse` [ParsedVariable "FOO" (Unquoted [CommandInterpolation "bin/foo" ["arg 1", "arg2"]])]++ it "parses a command with arguments separated by newlines" $ do+ parseConfig "FOO=$(foo.sh \"arg 1\"\narg2\n)"+ `shouldParse` [ParsedVariable "FOO" (Unquoted [CommandInterpolation "foo.sh" ["arg 1", "arg2"]])] it "parses empty content (when the file is empty)" $ parseConfig `shouldSucceedOn` ""
src/Configuration/Dotenv/Parse.hs view
@@ -20,11 +20,11 @@ import Control.Applicative (empty, many, some, (<|>)) import Control.Monad (void) import Data.Void (Void)+import qualified ShellWords import Text.Megaparsec (Parsec, anySingle, between, eof, noneOf, oneOf, sepEndBy, (<?>))-import Text.Megaparsec.Char (alphaNumChar, char,- digitChar, eol,+import Text.Megaparsec.Char (char, digitChar, eol, letterChar, spaceChar) import qualified Text.Megaparsec.Char.Lexer as L @@ -76,9 +76,11 @@ symbol = L.symbol sc interpolatedValueCommandInterpolation :: Parser VarFragment-interpolatedValueCommandInterpolation =- CommandInterpolation- <$> between (symbol "$(") (symbol ")") (many alphaNumChar)+interpolatedValueCommandInterpolation = do+ ws <- between (symbol "$(") (symbol ")") ShellWords.parser+ pure $ case ws of+ (commandName:arguments) -> CommandInterpolation commandName arguments+ _ -> VarLiteral "" -- Interpret "$()" as an empty value where symbol = L.symbol sc
src/Configuration/Dotenv/ParsedVariable.hs view
@@ -19,7 +19,7 @@ import Configuration.Dotenv.Environment (lookupEnv) import Control.Monad (foldM) import Control.Applicative ((<|>))-import System.Process (readCreateProcess, shell)+import System.Process (readCreateProcess, proc) data ParsedVariable = ParsedVariable VarName VarValue deriving (Show, Eq)@@ -36,7 +36,7 @@ data VarFragment = VarInterpolation String | VarLiteral String- | CommandInterpolation String deriving (Show, Eq)+ | CommandInterpolation String [String] deriving (Show, Eq) interpolateParsedVariables :: [ParsedVariable] -> IO [(String, String)] interpolateParsedVariables = fmap reverse . foldM addInterpolated []@@ -57,11 +57,11 @@ interpolateFragment previous (VarInterpolation varname) = fromPreviousOrEnv >>= maybe (return "") return where fromPreviousOrEnv = (lookup varname previous <|>) <$> lookupEnv varname-interpolateFragment _ (CommandInterpolation commandName) = init <$> readCreateProcess (shell commandName) ""+interpolateFragment _ (CommandInterpolation commandName args) = init <$> readCreateProcess (proc commandName args) "" joinContents :: VarContents -> String joinContents = concatMap fragmentToString where- fragmentToString (CommandInterpolation value) = value- fragmentToString (VarInterpolation value) = value- fragmentToString (VarLiteral value) = value+ fragmentToString (CommandInterpolation commandName args) = unwords $ commandName : args+ fragmentToString (VarInterpolation value) = value+ fragmentToString (VarLiteral value) = value