Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions dotconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,15 @@ const (
EnforceStructTags // Make sure all fields in config struct have `env` struct tags
AllowWhitespace // Allow leading/trailing whitespace in string values
SkipNewlineDecoding // Don't turn "\n" into newlines
SkipCommentStrip // Don't exclude the comment from value that ends with #some_inline_comment
)

type options struct {
ReturnFileIOErrors bool
EnforceStructTags bool
AllowWhitespace bool
SkipNewlineDecoding bool
SkipCommentStrip bool
}

func optsFromVariadic(opts []DecodeOption) options {
Expand All @@ -41,6 +43,8 @@ func optsFromVariadic(opts []DecodeOption) options {
v.AllowWhitespace = true
case SkipNewlineDecoding:
v.SkipNewlineDecoding = true
case SkipCommentStrip:
v.SkipCommentStrip = true
}
}
return v
Expand Down Expand Up @@ -113,9 +117,12 @@ func FromReader[T any](r io.Reader, opts ...DecodeOption) (T, error) {
key := line[0:strings.Index(line, "=")]
value := line[len(key)+1:]

// If there is a inline comment, so a space and then a #, exclude the comment.
if strings.Contains(value, " #") {
value = value[0:strings.Index(value, " #")]
if !decodedOpts.SkipCommentStrip {
// If there is a inline comment, so a space and then a #, exclude the comment.
ci := strings.Index(value, " #")
if ci >= 0 {
value = value[0:ci]
}
}

// Determine if our string is single quoted, double quoted, or just raw value.
Expand Down
38 changes: 38 additions & 0 deletions dotconfig_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -251,3 +251,41 @@ func TestAllowWhitespace(t *testing.T) {
t.Error("Expected to allow whitespace.")
}
}

func TestInlineComments(t *testing.T) {
const dotenv = `
# this is line comment
# and this also line comment
FOO=bar # this maybe part of FOO value (see SkipCommentStrip option)
`

type configT struct {
Foo string `env:"FOO"`
}

{
const expected = "bar"
r := strings.NewReader(dotenv)
config, err := dotconfig.FromReader[configT](r, dotconfig.EnforceStructTags)
if err != nil {
t.Fatalf("unexpected error (SkipCommentStrip disabled):%v", err)
}

if config.Foo != expected {
t.Errorf("incorrect parsed value (SkipCommentStrip disabled), expected: %s, actual: %s", expected, config.Foo)
}
}

{
const expected = "bar # this maybe part of FOO value (see SkipCommentStrip option)"
r := strings.NewReader(dotenv)
config, err := dotconfig.FromReader[configT](r, dotconfig.EnforceStructTags, dotconfig.SkipCommentStrip)
if err != nil {
t.Fatalf("unexpected error (SkipCommentStrip enabled) :%v", err)
}

if config.Foo != expected {
t.Errorf("incorrect parsed value (SkipCommentStrip enabled), expected: %s, actual: %s", expected, config.Foo)
}
}
}
Loading