From 3ac2e932ed47eca8784b4676170ffb7596841dfc Mon Sep 17 00:00:00 2001 From: Ulysses Souza Date: Tue, 11 Jan 2022 14:02:06 +0100 Subject: [PATCH] Handle inline comments on unquoted values Signed-off-by: Ulysses Souza --- fixtures/plain.env | 3 ++- fixtures/quoted.env | 2 +- godotenv_test.go | 15 ++++++++------- parser.go | 11 ++++------- 4 files changed, 15 insertions(+), 16 deletions(-) diff --git a/fixtures/plain.env b/fixtures/plain.env index 43f7e44..430914d 100644 --- a/fixtures/plain.env +++ b/fixtures/plain.env @@ -4,4 +4,5 @@ OPTION_C= 3 OPTION_D =4 OPTION_E = 5 OPTION_F = -OPTION_G= \ No newline at end of file +OPTION_G= +OPTION_H = my string # Inline comment diff --git a/fixtures/quoted.env b/fixtures/quoted.env index 7c4c19c..2f05d19 100644 --- a/fixtures/quoted.env +++ b/fixtures/quoted.env @@ -6,7 +6,7 @@ OPTION_E="1" OPTION_F="2" OPTION_G="" OPTION_H="\n" -OPTION_I = "echo 'asd'" +OPTION_I = "echo 'asd'" # Inline comment OPTION_J = 'first line second line third line diff --git a/godotenv_test.go b/godotenv_test.go index ad46519..5ec002d 100644 --- a/godotenv_test.go +++ b/godotenv_test.go @@ -80,6 +80,7 @@ func TestReadPlainEnv(t *testing.T) { "OPTION_E": "5", "OPTION_F": "", "OPTION_G": "", + "OPTION_H": "my string", } envMap, err := Read(envFileName) @@ -350,7 +351,7 @@ func TestParsing(t *testing.T) { // parses yaml style options parseAndCompare(t, "OPTION_A: 1", "OPTION_A", "1") - //parses yaml values with equal signs + // parses yaml values with equal signs parseAndCompare(t, "OPTION_A: Foo=bar", "OPTION_A", "Foo=bar") // parses non-yaml options with colons @@ -399,7 +400,7 @@ func TestParsing(t *testing.T) { parseAndCompare(t, `FOO="ba#r"`, "FOO", "ba#r") parseAndCompare(t, "FOO='ba#r'", "FOO", "ba#r") - //newlines and backslashes should be escaped + // newlines and backslashes should be escaped parseAndCompare(t, `FOO="bar\n\ b\az"`, "FOO", "bar\n baz") parseAndCompare(t, `FOO="bar\\\n\ b\az"`, "FOO", "bar\\\n baz") parseAndCompare(t, `FOO="bar\\r\ b\az"`, "FOO", "bar\\r baz") @@ -483,14 +484,14 @@ func TestWrite(t *testing.T) { t.Errorf("Expected '%v' (%v) to write as '%v', got '%v' instead.", env, envMap, expected, actual) } } - //just test some single lines to show the general idea - //TestRoundtrip makes most of the good assertions + // just test some single lines to show the general idea + // TestRoundtrip makes most of the good assertions - //values are always double-quoted + // values are always double-quoted writeAndCompare(`key=value`, `key="value"`) - //double-quotes are escaped + // double-quotes are escaped writeAndCompare(`key=va"lu"e`, `key="va\"lu\"e"`) - //but single quotes are left alone + // but single quotes are left alone writeAndCompare(`key=va'lu'e`, `key="va'lu'e"`) // newlines, backslashes, and some other special chars are escaped writeAndCompare(`foo="\n\r\\r!"`, `foo="\n\r\\r\!"`) diff --git a/parser.go b/parser.go index 1d144de..cdffc2c 100644 --- a/parser.go +++ b/parser.go @@ -131,17 +131,15 @@ func extractVarValue(src []byte, envMap map[string]string, lookupFn LookupFn) (v if !isQuoted { // unquoted value - read until new line end := bytes.IndexFunc(src, isNewLine) - var rest []byte var value string if end < 0 { - value := strings.TrimRightFunc(string(src), unicode.IsSpace) - rest = nil - return expandVariables(value, envMap, lookupFn), rest, nil + value := strings.Split(string(src), "#")[0] // Remove inline comments on unquoted lines + value = strings.TrimRightFunc(value, unicode.IsSpace) + return expandVariables(value, envMap, lookupFn), nil, nil } value = strings.TrimRightFunc(string(src[0:end]), unicode.IsSpace) - rest = src[end:] - return expandVariables(value, envMap, lookupFn), rest, nil + return expandVariables(value, envMap, lookupFn), src[end:], nil } // lookup quoted string terminator @@ -228,7 +226,6 @@ func isSpace(r rune) bool { return false } - // isNewLine reports whether the rune is a new line character func isNewLine(r rune) bool { return r == '\n'