Skip to content

Commit

Permalink
Merge pull request #340 from bkeepers/fix-comment-bug
Browse files Browse the repository at this point in the history
Fix 2.3.0 regressions and release 2.4.0
  • Loading branch information
jonmagic authored Apr 24, 2018
2 parents 924d3e6 + 9ef782c commit 089e9bd
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 64 deletions.
8 changes: 7 additions & 1 deletion Changelog.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
# Changelog

[Unreleased changes](https://github.com/bkeepers/dotenv/compare/v2.3.0...master)
[Unreleased changes](https://github.com/bkeepers/dotenv/compare/v2.4.0...master)

## 2.4.0 - Apr 23, 2018

This release reverts `Parse multiline values` ([#318](https://github.com/bkeepers/dotenv/pull/318), [#329](https://github.com/bkeepers/dotenv/pull/329)) due to a parsing regression that was discovered after the last release ([#336](https://github.com/bkeepers/dotenv/issues/336), [#339](https://github.com/bkeepers/dotenv/issues/339), [#341](https://github.com/bkeepers/dotenv/issues/341)).

[Full Changelog](https://github.com/bkeepers/dotenv/compare/v2.3.0...v2.4.0)

## 2.3.0 - Apr 19, 2018

Expand Down
14 changes: 1 addition & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,21 +116,9 @@ export SECRET_KEY=YOURSECRETKEYGOESHERE
If you need multiline variables, for example private keys, you can double quote strings and use the `\n` character for newlines:

```shell
PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\nHkVN9...\n-----END DSA PRIVATE KEY-----\n"
PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\nHkVN9\n-----END DSA PRIVATE KEY-----\n"
```

Alternatively, multi-line values with line breaks are now supported for quoted values.

```shell
PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----
...
HkVN9...
...
-----END DSA PRIVATE KEY-----"
```

This is particularly helpful when using the Heroku command line plugin [`heroku-config`](https://github.com/xavdid/heroku-config) to pull configuration variables down that may have line breaks.

### Command Substitution

You need to add the output of a command in one of your variables? Simply add it with `$(your_command)`:
Expand Down
22 changes: 11 additions & 11 deletions lib/dotenv/parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,21 @@ class Parser
[Dotenv::Substitutions::Variable, Dotenv::Substitutions::Command]

LINE = /
\A
\s*
(?:export\s+)? # optional export
([\w\.]+) # key
(?:\s*=\s*|:\s+?) # separator
( # optional value begin
'(?:\\'|[^'])*' # single quoted value
'(?:\'|[^'])*' # single quoted value
| # or
"(?:\\"|[^"])*" # double quoted value
"(?:\"|[^"])*" # double quoted value
| # or
[^#\r\n]+ # unquoted value
[^#\n]+ # unquoted value
)? # value end
\s*
(?:\#.*)? # optional comment
\z
/x

class << self
Expand All @@ -42,12 +44,7 @@ def initialize(string, is_load = false)
end

def call
# Process matches
@string.scan(LINE).each do |key, value|
@hash[key] = parse_value(value || "")
end
# Process non-matches
@string.gsub(LINE, "").split(/[\n\r]+/).each do |line|
@string.split(/[\n\r]+/).each do |line|
parse_line(line)
end
@hash
Expand All @@ -56,7 +53,10 @@ def call
private

def parse_line(line)
if line.split.first == "export"
if (match = line.match(LINE))
key, value = match.captures
@hash[key] = parse_value(value || "")
elsif line.split.first == "export"
if variable_not_set?(line)
raise FormatError, "Line #{line.inspect} has an unset variable"
end
Expand All @@ -65,7 +65,7 @@ def parse_line(line)

def parse_value(value)
# Remove surrounding quotes
value = value.strip.sub(/\A(['"])(.*)\1\z/m, '\2')
value = value.strip.sub(/\A(['"])(.*)\1\z/, '\2')

if Regexp.last_match(1) == '"'
value = unescape_characters(expand_newlines(value))
Expand Down
2 changes: 1 addition & 1 deletion lib/dotenv/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module Dotenv
VERSION = "2.3.0".freeze
VERSION = "2.4.0".freeze
end
46 changes: 8 additions & 38 deletions spec/dotenv/parser_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,14 @@ def env(string)
expect(env("\n\n\n # HERE GOES FOO \nfoo=bar")).to eql("foo" => "bar")
end

it "ignores commented out variables" do
expect(env("# HELLO=world\n")).to eql({})
end

it "ignores comment" do
expect(env("# Uncomment to activate:\n")).to eql({})
end

it "parses # in quoted values" do
expect(env('foo="ba#r"')).to eql("foo" => "ba#r")
expect(env("foo='ba#r'")).to eql("foo" => "ba#r")
Expand All @@ -161,44 +169,6 @@ def env(string)
expect(env("foo=")).to eql("foo" => "")
end

it "allows multi-line values in single quotes" do
env_file = %(OPTION_A=first line
export OPTION_B='line 1
line 2
line 3'
OPTION_C="last line"
OPTION_ESCAPED='line one
this is \\'quoted\\'
one more line')

expected_result = {
"OPTION_A" => "first line",
"OPTION_B" => "line 1\nline 2\nline 3",
"OPTION_C" => "last line",
"OPTION_ESCAPED" => "line one\nthis is \\'quoted\\'\none more line"
}
expect(env(env_file)).to eql(expected_result)
end

it "allows multi-line values in double quotes" do
env_file = %(OPTION_A=first line
export OPTION_B="line 1
line 2
line 3"
OPTION_C="last line"
OPTION_ESCAPED="line one
this is \\"quoted\\"
one more line")

expected_result = {
"OPTION_A" => "first line",
"OPTION_B" => "line 1\nline 2\nline 3",
"OPTION_C" => "last line",
"OPTION_ESCAPED" => "line one\nthis is \"quoted\"\none more line"
}
expect(env(env_file)).to eql(expected_result)
end

if RUBY_VERSION > "1.8.7"
it "parses shell commands interpolated in $()" do
expect(env("echo=$(echo hello)")).to eql("echo" => "hello")
Expand Down

0 comments on commit 089e9bd

Please sign in to comment.