From 616968dd63a1bc672290fb3adc933d3e37193aa0 Mon Sep 17 00:00:00 2001 From: Christophe Varoqui Date: Mon, 27 Jun 2022 11:10:46 +0200 Subject: [PATCH] Fix value format when SpaceBeforeInlineComment:true Setting the a#b value when SpaceBeforeInlineComment:true should not quote the value. --- file.go | 17 ++++++++++++++++- file_test.go | 44 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 1 deletion(-) diff --git a/file.go b/file.go index f8b2240..1810ed9 100644 --- a/file.go +++ b/file.go @@ -21,6 +21,7 @@ import ( "io" "io/ioutil" "os" + "regexp" "strings" "sync" ) @@ -47,6 +48,11 @@ type File struct { ValueMapper } +var ( + commentMarker = regexp.MustCompile(`[#;]`) + commentSpaceMarker = regexp.MustCompile(`\s+[#;]`) +) + // newFile initializes File object with given data sources. func newFile(dataSources []dataSource, opts LoadOptions) *File { if len(opts.KeyValueDelimiters) == 0 { @@ -444,6 +450,15 @@ func (f *File) writeToBuffer(indent string) (*bytes.Buffer, error) { kname = `"""` + kname + `"""` } + hasInlineComment := func(val string) bool { + if f.options.IgnoreInlineComment { + return false + } + if f.options.SpaceBeforeInlineComment { + return commentSpaceMarker.MatchString(val) + } + return commentMarker.MatchString(val) + } writeKeyValue := func(val string) (bool, error) { if _, err := buf.WriteString(kname); err != nil { return false, err @@ -462,7 +477,7 @@ func (f *File) writeToBuffer(indent string) (*bytes.Buffer, error) { // In case key value contains "\n", "`", "\"", "#" or ";" if strings.ContainsAny(val, "\n`") { val = `"""` + val + `"""` - } else if !f.options.IgnoreInlineComment && strings.ContainsAny(val, "#;") { + } else if hasInlineComment(val) { val = "`" + val + "`" } else if len(strings.TrimSpace(val)) != len(val) { val = `"` + val + `"` diff --git a/file_test.go b/file_test.go index c9914b5..eb2b270 100644 --- a/file_test.go +++ b/file_test.go @@ -457,6 +457,50 @@ test = }) + t.Run("support inline comments (no require space before)", func(t *testing.T) { + f, err := LoadSources(LoadOptions{SpaceBeforeInlineComment: false}, []byte{}) + require.NoError(t, err) + var buf bytes.Buffer + + f.Section("").Key("test").SetValue("a#b") + _, err = f.WriteTo(&buf) + require.NoError(t, err) + assert.Equal(t, "test = `a#b`\n", buf.String()) + }) + + t.Run("support inline comments (no require space before)", func(t *testing.T) { + f, err := LoadSources(LoadOptions{SpaceBeforeInlineComment: false}, []byte{}) + require.NoError(t, err) + var buf bytes.Buffer + + f.Section("").Key("test").SetValue("a #b") + _, err = f.WriteTo(&buf) + require.NoError(t, err) + assert.Equal(t, "test = `a #b`\n", buf.String()) + }) + + t.Run("support inline comments (require space before)", func(t *testing.T) { + f, err := LoadSources(LoadOptions{SpaceBeforeInlineComment: true}, []byte{}) + require.NoError(t, err) + var buf bytes.Buffer + + f.Section("").Key("test").SetValue("a#b") + _, err = f.WriteTo(&buf) + require.NoError(t, err) + assert.Equal(t, "test = a#b\n", buf.String()) + }) + + t.Run("support inline comments (require space before)", func(t *testing.T) { + f, err := LoadSources(LoadOptions{SpaceBeforeInlineComment: true}, []byte{}) + require.NoError(t, err) + var buf bytes.Buffer + + f.Section("").Key("test").SetValue("a #b") + _, err = f.WriteTo(&buf) + require.NoError(t, err) + assert.Equal(t, "test = `a #b`\n", buf.String()) + }) + t.Run("keep leading and trailing spaces in value", func(t *testing.T) { f, _ := Load([]byte(`[foo] bar1 = ' val ue1 '