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
34 changes: 26 additions & 8 deletions block.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,18 +62,28 @@ func splitsBlockLines(msg string, width int) ([]string, int) {
for _, line := range strings.Split(msg, "\n") {
line = strings.ReplaceAll(line, "\t", " ")
lastLinePos := 0
lastOpeningQuotePos := 0
inAnOpeningTag := false
inAClosingTag := false
inATagBody := false
inQuotes := false
length := 0
var lastChar rune
for pos, char := range line {
if char == '<' && lastChar != '\\' {
if len(line) > pos+1 && line[pos+1] == '/' {
inAClosingTag = true
inATagBody = false
} else {
inAnOpeningTag = true
if lastChar != '\\' {
switch char {
case '<':
if len(line) > pos+1 && line[pos+1] == '/' {
inAClosingTag = true
inATagBody = false
} else {
inAnOpeningTag = true
}
case '"':
inQuotes = !inQuotes
if inQuotes {
lastOpeningQuotePos = pos
}
}
}

Expand All @@ -92,10 +102,18 @@ func splitsBlockLines(msg string, width int) ([]string, int) {
}

if length >= width && !inAClosingTag && !inAnOpeningTag && !inATagBody {
// if we cross the line boundary but are currently within a
// quoted text, we jump back just before the opening quote
// because we don't want to cut the text inside
if inQuotes && lastOpeningQuotePos > lastLinePos {
length = pos - lastOpeningQuotePos
pos = lastOpeningQuotePos - 1
} else {
maxLen = width
length = 0
}
lines = append(lines, line[lastLinePos:pos+1])
maxLen = width
lastLinePos = pos + 1
length = 0
}

lastChar = char
Expand Down
14 changes: 14 additions & 0 deletions block_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,20 @@ func (ts *OutputBlockSuite) TestSplitsBlockLines(c *C) {
c.Assert(maxLen, Equals, 3)
}

func (ts *OutputBlockSuite) TestEnclosedWithQuotes(c *C) {
lines, maxLen := splitsBlockLines(`The "foo bar" file has moved to "a very long path". Please consider it.`, 40)
c.Assert(lines, DeepEquals, []string{`The "foo bar" file has moved to `, `"a very long path". Please consider it.`})
c.Assert(maxLen, Equals, 38)

lines, maxLen = splitsBlockLines(`The "foo bar" file has moved to "a very very very very very very very very very unterminated long path.`, 40)
c.Assert(lines, DeepEquals, []string{`The "foo bar" file has moved to `, `"a very very very very very very very ver`, `y very unterminated long path.`})
c.Assert(maxLen, Equals, 40)

lines, maxLen = splitsBlockLines(`This is an example of a message about a "/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/long/path" that needs to be moved to "/another/very/very/very/very/very/very/very/long/path"`, 107)
c.Assert(lines, DeepEquals, []string{`This is an example of a message about a `, `"/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/very/long/path" that needs`, ` to be moved to "/another/very/very/very/very/very/very/very/long/path"`})
c.Assert(maxLen, Equals, 107)
}

func (ts *OutputBlockSuite) TestSplitsBlockLinesDonotPanic(c *C) {
lines, maxLen := splitsBlockLines("Foo Baz<", 4)
c.Assert(lines, DeepEquals, []string{"Foo ", "Baz<"})
Expand Down