mirror of
https://github.com/caddyserver/caddy.git
synced 2026-11-11 19:37:55 +00:00
caddyfile: keep an opening brace that ends the input (#8047)
* caddyfile: Keep an opening brace that ends the input
Format writes an opening brace lazily: the '{' case records the pending
brace and continues, and the brace is only emitted once a following
regular character is processed. When the input ends while a brace is
still pending, the read loop exits and nothing flushes it, so the brace
is dropped. 'caddy fmt' on a Caddyfile whose last line has just opened a
block therefore deletes the brace the user typed, and with --overwrite
that result is written back over the file.
Flush a pending brace after the loop ends. This also restores
idempotence for inputs such as '{ {', which formatted to '{' and then to
nothing.
* caddyfile: Flush a pending brace before another one replaces it
The '{' case overwrote the pending-brace state without emitting the
brace already waiting, so adjacent braces lost one: Format("{{") gave
just "{". Only the space-separated path flushed, and it did so with an
inline block.
Move that block into a flushOpenBrace closure and call it from the three
places a pending brace has to be emitted: the existing space-separated
path, the '{' case before it replaces the state, and the end of input.
Using it at the end of input also indents a trailing brace the same way
the other paths do.
This commit is contained in:
1 parent
2f34b936f5
commit
b72bf7a1ef
2 files changed
+58
-25
No files matched your search
@@ -106,6 +106,34 @@ func Format(input []byte) []byte {
|
||||
beginningOfLine = true
|
||||
}
|
||||
|
||||
flushOpenBrace := func() {
|
||||
if nesting == 0 && last == '}' {
|
||||
nextLine()
|
||||
nextLine()
|
||||
}
|
||||
|
||||
openBrace = false
|
||||
if openBraceOwnLine && previousLineWasTopLevelImport {
|
||||
if last != '\n' {
|
||||
nextLine()
|
||||
}
|
||||
indent()
|
||||
} else if beginningOfLine {
|
||||
indent()
|
||||
} else if !openBraceSpace || !unicode.IsSpace(last) {
|
||||
write(' ')
|
||||
}
|
||||
write('{')
|
||||
openBraceWritten = true
|
||||
openBraceOwnLine = false
|
||||
nextLine()
|
||||
newLines = 0
|
||||
// prevent infinite nesting from ridiculous inputs (issue #4169)
|
||||
if nesting < 10 {
|
||||
nesting++
|
||||
}
|
||||
}
|
||||
|
||||
for {
|
||||
ch, _, err := rdr.ReadRune()
|
||||
if err != nil {
|
||||
@@ -270,36 +298,15 @@ func Format(input []byte) []byte {
|
||||
}
|
||||
|
||||
if openBrace && spacePrior && !openBraceWritten {
|
||||
if nesting == 0 && last == '}' {
|
||||
nextLine()
|
||||
nextLine()
|
||||
}
|
||||
|
||||
openBrace = false
|
||||
if openBraceOwnLine && previousLineWasTopLevelImport {
|
||||
if last != '\n' {
|
||||
nextLine()
|
||||
}
|
||||
indent()
|
||||
} else if beginningOfLine {
|
||||
indent()
|
||||
} else if !openBraceSpace || !unicode.IsSpace(last) {
|
||||
write(' ')
|
||||
}
|
||||
write('{')
|
||||
openBraceWritten = true
|
||||
openBraceOwnLine = false
|
||||
nextLine()
|
||||
newLines = 0
|
||||
// prevent infinite nesting from ridiculous inputs (issue #4169)
|
||||
if nesting < 10 {
|
||||
nesting++
|
||||
}
|
||||
flushOpenBrace()
|
||||
}
|
||||
|
||||
switch {
|
||||
case ch == '{':
|
||||
finishToken()
|
||||
if openBrace && !openBraceWritten {
|
||||
flushOpenBrace()
|
||||
}
|
||||
openBrace = true
|
||||
openBraceSpace = spacePrior && !beginningOfLine
|
||||
openBraceOwnLine = newLines > 0
|
||||
@@ -367,6 +374,10 @@ func Format(input []byte) []byte {
|
||||
beginningOfLine = false
|
||||
}
|
||||
|
||||
if openBrace && !openBraceWritten {
|
||||
flushOpenBrace()
|
||||
}
|
||||
|
||||
// the Caddyfile does not need any leading or trailing spaces, but...
|
||||
trimmedResult := bytes.TrimSpace(out.Bytes())
|
||||
|
||||
|
||||
@@ -495,6 +495,28 @@ import ./conf.d/matcher_not_my_subnet.caddy
|
||||
order appsec after crowdsec
|
||||
}`,
|
||||
},
|
||||
{
|
||||
description: "keep an opening brace that ends the input",
|
||||
input: `localhost {`,
|
||||
expect: `localhost {`,
|
||||
},
|
||||
{
|
||||
description: "keep a standalone opening brace that ends the input",
|
||||
input: `{`,
|
||||
expect: `{`,
|
||||
},
|
||||
{
|
||||
description: "keep adjacent opening braces that end the input",
|
||||
input: `{{`,
|
||||
expect: `{
|
||||
{`,
|
||||
},
|
||||
{
|
||||
description: "keep spaced opening braces that end the input",
|
||||
input: `{ {`,
|
||||
expect: `{
|
||||
{`,
|
||||
},
|
||||
} {
|
||||
// the formatter should output a trailing newline,
|
||||
// even if the tests aren't written to expect that
|
||||
|
||||
Reference in new issue
Block a user