Skip to content

Commit

Permalink
fix: normalise whitespace in messages, support preformatted details (#22
Browse files Browse the repository at this point in the history
)
  • Loading branch information
kangasta authored Nov 23, 2023
1 parent 9ece10f commit 8c6dcbb
Show file tree
Hide file tree
Showing 8 changed files with 91 additions and 19 deletions.
9 changes: 8 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ The format is based on [keep a changelog](https://keepachangelog.com/en/1.0.0/)

## [Unreleased]

## [v1.0.2] - 2022-11-23

### Fixed
- Normalise whitespace (`\s`` `) in messages to avoid newlines and tabs breaking in-progress message updating.
- Assume details message to be preformatted, if it contains newline characters (`\n`). Preformatted message details are wrapped so that newline characters are maintained. This makes, for example, stack traces and console output in message details more readable.

## [v1.0.1] - 2022-08-30

### Fixed
Expand All @@ -17,6 +23,7 @@ The format is based on [keep a changelog](https://keepachangelog.com/en/1.0.0/)
- Extract and refactor livelog functionality from [UpCloud CLI (`upctl`)](https://github.com/UpCloudLtd/upcloud-cli.git).


[Unreleased]: https://github.com/UpCloudLtd/progress/compare/v1.0.1...HEAD
[Unreleased]: https://github.com/UpCloudLtd/progress/compare/v1.0.2...HEAD
[v1.0.2]: https://github.com/UpCloudLtd/progress/compare/v1.0.1...v1.0.2
[v1.0.1]: https://github.com/UpCloudLtd/progress/compare/v1.0.0...v1.0.1
[v1.0.0]: https://github.com/UpCloudLtd/progress/releases/tag/v1.0.0
12 changes: 6 additions & 6 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
module github.com/UpCloudLtd/progress

go 1.18
go 1.20

require (
github.com/bradleyjkemp/cupaloy/v2 v2.7.0
github.com/jedib0t/go-pretty/v6 v6.3.3
github.com/stretchr/testify v1.8.0
golang.org/x/term v0.0.0-20220526004731-065cf7ba2467
github.com/bradleyjkemp/cupaloy/v2 v2.8.0
github.com/jedib0t/go-pretty/v6 v6.4.9
github.com/stretchr/testify v1.8.4
golang.org/x/term v0.14.0
)

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/mattn/go-runewidth v0.0.13 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rivo/uniseg v0.2.0 // indirect
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 // indirect
golang.org/x/sys v0.14.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
22 changes: 11 additions & 11 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
github.com/bradleyjkemp/cupaloy/v2 v2.7.0 h1:AT0vOjO68RcLyenLCHOGZzSNiuto7ziqzq6Q1/3xzMQ=
github.com/bradleyjkemp/cupaloy/v2 v2.7.0/go.mod h1:bm7JXdkRd4BHJk9HpwqAI8BoAY1lps46Enkdqw6aRX0=
github.com/bradleyjkemp/cupaloy/v2 v2.8.0 h1:any4BmKE+jGIaMpnU8YgH/I2LPiLBufr6oMMlVBbn9M=
github.com/bradleyjkemp/cupaloy/v2 v2.8.0/go.mod h1:bm7JXdkRd4BHJk9HpwqAI8BoAY1lps46Enkdqw6aRX0=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/jedib0t/go-pretty/v6 v6.3.3 h1:shEWoyXqldeP54byATY3IczSfMC1b/UziOISaSxcvMQ=
github.com/jedib0t/go-pretty/v6 v6.3.3/go.mod h1:MgmISkTWDSFu0xOqiZ0mKNntMQ2mDgOcwOkwBEkMDJI=
github.com/jedib0t/go-pretty/v6 v6.4.9 h1:vZ6bjGg2eBSrJn365qlxGcaWu09Id+LHtrfDWlB2Usc=
github.com/jedib0t/go-pretty/v6 v6.4.9/go.mod h1:Ndk3ase2CkQbXLLNf5QDHoYb6J9WtVfmHZu9n8rk2xs=
github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU=
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/pkg/profile v1.6.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18=
Expand All @@ -18,13 +18,13 @@ github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSS
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.4/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1 h1:SrN+KX8Art/Sf4HNj6Zcz06G7VEz+7w9tdXTPOZ7+l4=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20220526004731-065cf7ba2467 h1:CBpWXWQpIRjzmkkA+M7q9Fqnwd2mZr3AFqexg8YTfoM=
golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.14.0 h1:LGK9IlZ8T9jvdy6cTdfKUCltatMFOehAQo9SRC46UQ8=
golang.org/x/term v0.14.0/go.mod h1:TySc+nGkYR6qt8km8wUhuFRTVSMIX3XPR58y2lC8vww=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@
✓ Test success (100s)  100 s
✗ Test error, 10 % (1000s, % char in message)  > 999 s
Error: Short dummy error message
✗ Test invalid message with tabs and newlines (5s, \n and \t chars in message)  5 s
✗ Test details with newlines (15s, \n chars in details)  15 s
Output:

+ echo 'Details with newlines are assumed to be preformatted. Thus, newline characters should not 
be replaced with other whitespace when wrapping the text.'
Details with newlines are assumed to be preformatted. Thus, newline characters should not be repla
ced with other whitespace when wrapping the text.
+ cat not-found
cat: not-found: No such file or directory
! Test warning (10s, long message) - Lorem ipsum dolor sit amet, consectetur adipiscing eli… > 999 s
Error: Long dummy error message - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do 
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud 
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@
✓ Test success (100s) 100 s
✗ Test error, 10 % (1000s, % char in message) > 999 s
Error: Short dummy error message
✗ Test invalid message with tabs and newlines (5s, \n and \t chars in message) 5 s
✗ Test details with newlines (15s, \n chars in details) 15 s
Output:

+ echo 'Details with newlines are assumed to be preformatted. Thus, newline characters should not
be replaced with other whitespace when wrapping the text.'
Details with newlines are assumed to be preformatted. Thus, newline characters should not be repla
ced with other whitespace when wrapping the text.
+ cat not-found
cat: not-found: No such file or directory
! Test warning (10s, long message) - Lorem ipsum dolor sit amet, consectetur adipiscing eli… > 999 s
Error: Long dummy error message - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@
Test success (100s)  100 s
Test error, 10 % (1000s, % char in message)  > 999 s
Error: Short dummy error message
Test invalid message with tabs and newlines (5s, \n and \t chars in message)  5 s
Test details with newlines (15s, \n chars in details)  15 s
Output:

+ echo 'Details with newlines are assumed to be preformatted. Thus, newline characters should not 
be replaced with other whitespace when wrapping the text.'
Details with newlines are assumed to be preformatted. Thus, newline characters should not be repla
ced with other whitespace when wrapping the text.
+ cat not-found
cat: not-found: No such file or directory
Test warning (10s, long message) - Lorem ipsum dolor sit amet, consectetur adipiscing elit,… > 999 s
Error: Long dummy error message - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do 
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud 
Expand Down
13 changes: 12 additions & 1 deletion messages/output.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"io"
"math"
"os"
"regexp"
"strings"

"github.com/UpCloudLtd/progress/terminal"
Expand All @@ -18,6 +19,8 @@ const (
RenderStateDone RenderState = -1
)

var whitespace = regexp.MustCompile(`\s`)

type OutputConfig struct {
DefaultTextWidth int
DisableColors bool
Expand Down Expand Up @@ -171,7 +174,14 @@ func (cfg OutputConfig) GetMaxHeight() int {

func (cfg OutputConfig) formatDetails(msg *Message) string {
wrapWidth := cfg.GetMaxWidth() - 2
details := text.WrapSoft(cfg.getDetailsColor().Sprint(msg.Details), wrapWidth)

var details string
// If details contains newline characters, assume that details are preformatted (e.g., stack trace, console output, ...)
if strings.Contains(msg.Details, "\n") {
details = text.WrapText(cfg.getDetailsColor().Sprint(msg.Details), wrapWidth)
} else {
details = text.WrapSoft(cfg.getDetailsColor().Sprint(msg.Details), wrapWidth)
}

if cfg.ShowStatusIndicator {
return strings.ReplaceAll("\n"+details, "\n", "\n ")
Expand Down Expand Up @@ -206,6 +216,7 @@ func (cfg OutputConfig) GetMessageText(msg *Message, renderState RenderState) st
if maxMessageWidth < 0 {
return ""
}
message = whitespace.ReplaceAllString(message, " ")
if len(message) > maxMessageWidth {
message = fmt.Sprintf("%s…", message[:maxMessageWidth-1])
} else {
Expand Down
24 changes: 24 additions & 0 deletions messages/output_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,13 @@ import (
"github.com/stretchr/testify/assert"
)

const detailsWithNewlines = `Output:
+ echo 'Details with newlines are assumed to be preformatted. Thus, newline characters should not be replaced with other whitespace when wrapping the text.'
Details with newlines are assumed to be preformatted. Thus, newline characters should not be replaced with other whitespace when wrapping the text.
+ cat not-found
cat: not-found: No such file or directory`

const loremIpsum = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."

func TestMessageRenderer_RenderMessageStore(t *testing.T) {
Expand Down Expand Up @@ -97,6 +104,23 @@ func TestMessageRenderer_RenderMessageStore(t *testing.T) {
})
assert.NoError(t, err)

err = store.Add(messages.Message{
Message: "Test\tinvalid\nmessage\twith\ntabs\tand\nnewlines (5s, \\n and \\t chars in message)",
Status: messages.MessageStatusError,
Started: time.Now().Add(time.Second * -5),
Finished: time.Now(),
})
assert.NoError(t, err)

err = store.Add(messages.Message{
Message: "Test details with newlines (15s, \\n chars in details)",
Status: messages.MessageStatusError,
Details: detailsWithNewlines,
Started: time.Now().Add(time.Second * -15),
Finished: time.Now(),
})
assert.NoError(t, err)

err = store.Add(messages.Message{
Message: "Test warning (10s, long message) - " + loremIpsum,
Status: messages.MessageStatusWarning,
Expand Down

0 comments on commit 8c6dcbb

Please sign in to comment.