Skip to content

Commit 589be99

Browse files
authored
Merge pull request #10 from breml/fix-formatting-multiline-string
Fix formatting multiline string
2 parents 15df4bd + 238da34 commit 589be99

File tree

3 files changed

+146
-3
lines changed

3 files changed

+146
-3
lines changed

ast/ast_helper.go

+11-3
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,17 @@ package ast
33
import (
44
"bytes"
55
"fmt"
6+
"regexp"
67
"strings"
78
)
89

10+
// This regular expression splits the config into indentable chunks that are:
11+
// * empty line
12+
// * line of comment
13+
// * line without any quotes
14+
// * line(s) with quoted strings, which are kept together to form a single "line of configuration"
15+
var linesRe = regexp.MustCompile(`(\n|\s*//[^\n]*\n|[^'"\n]*\n|([^"'\n]*("(\\"|[^"])*"|'(\\'|[^'])*')[^"'\n]*)*\n)`)
16+
917
func prefix(in string, emptyNewline bool) string {
1018
if len(in) == 0 {
1119
if emptyNewline {
@@ -16,13 +24,13 @@ func prefix(in string, emptyNewline bool) string {
1624

1725
var s bytes.Buffer
1826
s.WriteString("\n")
19-
lines := strings.Split(strings.TrimRight(in, "\n"), "\n")
27+
lines := linesRe.FindAllString(strings.TrimRight(in, "\n")+"\n", -1)
2028
for _, l := range lines {
21-
if len(l) == 0 {
29+
if len(strings.TrimLeft(l, " \n")) == 0 {
2230
s.WriteString("\n")
2331
continue
2432
}
25-
s.WriteString(fmt.Sprintln(" " + l))
33+
s.WriteString(fmt.Sprint(" " + l))
2634
}
2735
return s.String()
2836
}

ast/ast_helper_test.go

+122
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
package ast
2+
3+
import "testing"
4+
5+
func TestPrefix(t *testing.T) {
6+
tt := []struct {
7+
name string
8+
input string
9+
emptyNewline bool
10+
11+
want string
12+
}{
13+
{
14+
name: "empty string",
15+
},
16+
{
17+
name: `empty string with empty newline`,
18+
emptyNewline: true,
19+
20+
want: "\n",
21+
},
22+
{
23+
name: "simple attribute",
24+
input: `value => 3.1415
25+
`,
26+
27+
want: `
28+
value => 3.1415
29+
`,
30+
},
31+
{
32+
name: "simple attribute with comment",
33+
input: `// comment
34+
value => 3.1415
35+
`,
36+
37+
want: `
38+
// comment
39+
value => 3.1415
40+
`,
41+
},
42+
{
43+
name: "block",
44+
input: `add_field {
45+
// comment
46+
value => 3.1415
47+
}
48+
49+
add_tag => [ "foobar" ]
50+
`,
51+
52+
want: `
53+
add_field {
54+
// comment
55+
value => 3.1415
56+
}
57+
58+
add_tag => [ "foobar" ]
59+
`,
60+
},
61+
{
62+
name: "attribute with multiline string attribute",
63+
input: `value => "string
64+
with multiple
65+
lines"
66+
othervalue => 3.1415
67+
`,
68+
69+
want: `
70+
value => "string
71+
with multiple
72+
lines"
73+
othervalue => 3.1415
74+
`,
75+
},
76+
{
77+
name: "attribute with multiline string attribute (single quote)",
78+
input: `value => 'string
79+
with multiple
80+
lines'
81+
othervalue => 3.1415
82+
`,
83+
84+
want: `
85+
value => 'string
86+
with multiple
87+
lines'
88+
othervalue => 3.1415
89+
`,
90+
},
91+
{
92+
name: "comment with double and single quote",
93+
input: `// comment with " and '
94+
othervalue => 3.1415
95+
`,
96+
97+
want: `
98+
// comment with " and '
99+
othervalue => 3.1415
100+
`,
101+
},
102+
{
103+
name: "array with multiple string types",
104+
input: `value => [ "string", 'string', string ]
105+
`,
106+
107+
want: `
108+
value => [ "string", 'string', string ]
109+
`,
110+
},
111+
}
112+
113+
for _, tc := range tt {
114+
t.Run(tc.name, func(t *testing.T) {
115+
got := prefix(tc.input, tc.emptyNewline)
116+
117+
if tc.want != got {
118+
t.Errorf("want %q, got %q", tc.want, got)
119+
}
120+
})
121+
}
122+
}

logstash_config_test.go

+13
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,19 @@ output {}
368368
}
369369
}
370370
}
371+
`,
372+
},
373+
{
374+
name: "multiline string",
375+
input: `filter {
376+
mutate {
377+
add_field => {
378+
"largeint" => "a string
379+
with multiple
380+
lines"
381+
}
382+
}
383+
}
371384
`,
372385
},
373386
}

0 commit comments

Comments
 (0)