@marcel91200 / caddy Mirror · read-only / commits / c0273f1f
Fork 0

Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS

Mirrored from https://github.com/Slazee/caddy.git

Synced Nov 12, 18:15 UTC

caddyfile: Add heredoc support to `fmt` command (#6056)

bbaa committed Jan 22, 2024 at 10:24 UTC c0273f1f049aa66e4426023d8e43d68fbdbccbb6
3 files changed +145 -1
caddyconfig/caddyfile/formatter.go
+74
@@ -31,6 +31,14 @@ func Format(input []byte) []byte {
31 out := new(bytes.Buffer)
32 rdr := bytes.NewReader(input)
33
34 + type heredocState int
35 +
36 + const (
37 + heredocClosed heredocState = 0
38 + heredocOpening heredocState = 1
39 + heredocOpened heredocState = 2
40 + )
41 +
42 var (
43 last rune // the last character that was written to the result
44
@@ -47,6 +55,11 @@ func Format(input []byte) []byte {
55 quoted bool // whether we're in a quoted segment
56 escaped bool // whether current char is escaped
57
58 + heredoc heredocState // whether we're in a heredoc
59 + heredocEscaped bool // whether heredoc is escaped
60 + heredocMarker []rune
61 + heredocClosingMarker []rune
62 +
63 nesting int // indentation level
64 )
65
@@ -75,6 +88,58 @@ func Format(input []byte) []byte {
88 panic(err)
89 }
90
91 + // detect whether we have the start of a heredoc
92 + if !quoted && !(heredoc != heredocClosed || heredocEscaped) &&
93 + space && last == '<' && ch == '<' {
94 + write(ch)
95 + heredoc = heredocOpening
96 + space = false
97 + continue
98 + }
99 +
100 + if heredoc == heredocOpening {
101 + if ch == '\n' {
102 + if len(heredocMarker) > 0 && heredocMarkerRegexp.MatchString(string(heredocMarker)) {
103 + heredoc = heredocOpened
104 + } else {
105 + heredocMarker = nil
106 + heredoc = heredocClosed
107 + nextLine()
108 + continue
109 + }
110 + write(ch)
111 + continue
112 + }
113 + if unicode.IsSpace(ch) {
114 + // a space means it's just a regular token and not a heredoc
115 + heredocMarker = nil
116 + heredoc = heredocClosed
117 + } else {
118 + heredocMarker = append(heredocMarker, ch)
119 + write(ch)
120 + continue
121 + }
122 + }
123 + // if we're in a heredoc, all characters are read&write as-is
124 + if heredoc == heredocOpened {
125 + write(ch)
126 + heredocClosingMarker = append(heredocClosingMarker, ch)
127 + if len(heredocClosingMarker) > len(heredocMarker) {
128 + heredocClosingMarker = heredocClosingMarker[1:]
129 + }
130 + // check if we're done
131 + if string(heredocClosingMarker) == string(heredocMarker) {
132 + heredocMarker = nil
133 + heredocClosingMarker = nil
134 + heredoc = heredocClosed
135 + }
136 + continue
137 + }
138 +
139 + if last == '<' && space {
140 + space = false
141 + }
142 +
143 if comment {
144 if ch == '\n' {
145 comment = false
@@ -98,6 +163,9 @@ func Format(input []byte) []byte {
163 }
164
165 if escaped {
166 + if ch == '<' {
167 + heredocEscaped = true
168 + }
169 write(ch)
170 escaped = false
171 continue
@@ -117,6 +185,7 @@ func Format(input []byte) []byte {
185
186 if unicode.IsSpace(ch) {
187 space = true
188 + heredocEscaped = false
189 if ch == '\n' {
190 newLines++
191 }
@@ -205,6 +274,11 @@ func Format(input []byte) []byte {
274 write('{')
275 openBraceWritten = true
276 }
277 +
278 + if spacePrior && ch == '<' {
279 + space = true
280 + }
281 +
282 write(ch)
283
284 beginningOfLine = false
caddyconfig/caddyfile/formatter_test.go
+70
@@ -362,6 +362,76 @@ block {
362
363 block {
364 }
365 +`,
366 + },
367 + {
368 + description: "keep heredoc as-is",
369 + input: `block {
370 + heredoc <<HEREDOC
371 + Here's more than one space Here's more than one space
372 + HEREDOC
373 +}
374 +`,
375 + expect: `block {
376 + heredoc <<HEREDOC
377 + Here's more than one space Here's more than one space
378 + HEREDOC
379 +}
380 +`,
381 + },
382 + {
383 + description: "Mixing heredoc with regular part",
384 + input: `block {
385 + heredoc <<HEREDOC
386 + Here's more than one space Here's more than one space
387 + HEREDOC
388 + respond "More than one space will be eaten" 200
389 +}
390 +
391 +block2 {
392 + heredoc <<HEREDOC
393 + Here's more than one space Here's more than one space
394 + HEREDOC
395 + respond "More than one space will be eaten" 200
396 +}
397 +`,
398 + expect: `block {
399 + heredoc <<HEREDOC
400 + Here's more than one space Here's more than one space
401 + HEREDOC
402 + respond "More than one space will be eaten" 200
403 +}
404 +
405 +block2 {
406 + heredoc <<HEREDOC
407 + Here's more than one space Here's more than one space
408 + HEREDOC
409 + respond "More than one space will be eaten" 200
410 +}
411 +`,
412 + },
413 + {
414 + description: "Heredoc as regular token",
415 + input: `block {
416 + heredoc <<HEREDOC "More than one space will be eaten"
417 +}
418 +`,
419 + expect: `block {
420 + heredoc <<HEREDOC "More than one space will be eaten"
421 +}
422 +`,
423 + },
424 + {
425 + description: "Escape heredoc",
426 + input: `block {
427 + heredoc \<<HEREDOC
428 + respond "More than one space will be eaten" 200
429 +}
430 +`,
431 + expect: `block {
432 + heredoc \<<HEREDOC
433 + respond "More than one space will be eaten" 200
434 +}
435 `,
436 },
437 } {
caddyconfig/caddyfile/lexer.go
+1 -1
@@ -313,7 +313,7 @@ func (l *lexer) finalizeHeredoc(val []rune, marker string) ([]rune, error) {
313 // iterate over each line and strip the whitespace from the front
314 var out string
315 for lineNum, lineText := range lines[:len(lines)-1] {
316 - if lineText == "" {
316 + if lineText == "" || lineText == "\r" {
317 out += "\n"
318 continue
319 }