Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

progress: Tracker.UpdateMessage(...) to safely update message #162

Merged
merged 1 commit into from
Apr 22, 2021
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
38 changes: 20 additions & 18 deletions progress/render.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,11 +195,12 @@ func (p *Progress) moveCursorToTheTop(out *strings.Builder) {
}

func (p *Progress) renderTracker(out *strings.Builder, t *Tracker, hint renderHint) {
if strings.Contains(t.Message, "\t") {
t.Message = strings.Replace(t.Message, "\t", " ", -1)
message := t.message()
if strings.Contains(message, "\t") {
t.Message = strings.Replace(message, "\t", " ", -1)
}
if strings.Contains(t.Message, "\r") {
t.Message = strings.Replace(t.Message, "\r", "", -1)
if strings.Contains(message, "\r") {
t.Message = strings.Replace(message, "\r", "", -1)
}

out.WriteString(text.EraseLine.Sprint())
Expand All @@ -223,7 +224,7 @@ func (p *Progress) renderTracker(out *strings.Builder, t *Tracker, hint renderHi
}

func (p *Progress) renderTrackerDone(out *strings.Builder, t *Tracker) {
out.WriteString(p.style.Colors.Message.Sprint(t.Message))
out.WriteString(p.style.Colors.Message.Sprint(t.message()))
out.WriteString(p.style.Colors.Message.Sprint(p.style.Options.Separator))
if !t.IsErrored() {
out.WriteString(p.style.Colors.Message.Sprint(p.style.Options.DoneString))
Expand All @@ -236,11 +237,12 @@ func (p *Progress) renderTrackerDone(out *strings.Builder, t *Tracker) {

func (p *Progress) renderTrackerProgress(out *strings.Builder, t *Tracker, trackerStr string, hint renderHint) {
if p.messageWidth > 0 {
messageLen := text.RuneCount(t.Message)
message := t.message()
messageLen := text.RuneCount(message)
if messageLen < p.messageWidth {
t.Message = text.Pad(t.Message, p.messageWidth, ' ')
t.UpdateMessage(text.Pad(message, p.messageWidth, ' '))
} else {
t.Message = text.Snip(t.Message, p.messageWidth, p.style.Options.SnipIndicator)
t.UpdateMessage(text.Snip(message, p.messageWidth, p.style.Options.SnipIndicator))
}
}

Expand All @@ -249,11 +251,7 @@ func (p *Progress) renderTrackerProgress(out *strings.Builder, t *Tracker, track
p.renderTrackerStats(out, t, hint)
out.WriteRune('\n')
} else if p.trackerPosition == PositionRight {
if !t.IsErrored() {
out.WriteString(p.style.Colors.Message.Sprint(t.Message))
} else {
out.WriteString(p.style.Colors.Error.Sprint(t.Message))
}
p.renderTrackerMessage(out, t)
out.WriteString(p.style.Colors.Message.Sprint(p.style.Options.Separator))
p.renderTrackerPercentage(out, t)
if !p.hideTracker {
Expand All @@ -268,15 +266,19 @@ func (p *Progress) renderTrackerProgress(out *strings.Builder, t *Tracker, track
}
p.renderTrackerStats(out, t, hint)
out.WriteString(p.style.Colors.Message.Sprint(p.style.Options.Separator))
if !t.IsErrored() {
out.WriteString(p.style.Colors.Message.Sprint(t.Message))
} else {
out.WriteString(p.style.Colors.Error.Sprint(t.Message))
}
p.renderTrackerMessage(out, t)
out.WriteRune('\n')
}
}

func (p *Progress) renderTrackerMessage(out *strings.Builder, t *Tracker) {
if !t.IsErrored() {
out.WriteString(p.style.Colors.Message.Sprint(t.message()))
} else {
out.WriteString(p.style.Colors.Error.Sprint(t.message()))
}
}

func (p *Progress) renderTrackerPercentage(out *strings.Builder, t *Tracker) {
if !p.hidePercentage {
var percentageStr string
Expand Down
5 changes: 1 addition & 4 deletions progress/render_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,7 @@ func trackSomethingErrored(pw Writer, tracker *Tracker) {
if tracker.value+incrementPerCycle > total {
tracker.MarkAsErrored()
} else {
tracker.Increment(incrementPerCycle)
}
if tracker.Value() >= total {
tracker.MarkAsErrored()
tracker.IncrementWithError(incrementPerCycle)
}
}
}
Expand Down
18 changes: 17 additions & 1 deletion progress/tracker.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@ import (
// Writer.AppendTracker() method. When the task that is being done has progress,
// increment the value using the Tracker.Increment(value) method.
type Tracker struct {
// Message should contain a short description of the "task"
// Message should contain a short description of the "task"; please note
// that this should NOT be updated in the middle of progress - you should
// instead use UpdateMessage() to do this safely without hitting any race
// conditions
Message string
// ExpectedDuration tells how long this task is expected to take; and will
// be used in calculation of the ETA value
Expand Down Expand Up @@ -148,13 +151,26 @@ func (t *Tracker) SetValue(value int64) {
t.mutex.Unlock()
}

// UpdateMessage updates the message string.
func (t *Tracker) UpdateMessage(msg string) {
t.mutex.Lock()
t.Message = msg
t.mutex.Unlock()
}

// Value returns the current value of the tracker.
func (t *Tracker) Value() int64 {
t.mutex.RLock()
defer t.mutex.RUnlock()
return t.value
}

func (t *Tracker) message() string {
t.mutex.RLock()
defer t.mutex.RUnlock()
return t.Message
}

func (t *Tracker) valueAndTotal() (int64, int64) {
t.mutex.RLock()
value := t.value
Expand Down
4 changes: 2 additions & 2 deletions progress/tracker_sort.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,13 @@ type sortByMessage []*Tracker

func (sb sortByMessage) Len() int { return len(sb) }
func (sb sortByMessage) Swap(i, j int) { sb[i], sb[j] = sb[j], sb[i] }
func (sb sortByMessage) Less(i, j int) bool { return sb[i].Message < sb[j].Message }
func (sb sortByMessage) Less(i, j int) bool { return sb[i].message() < sb[j].message() }

type sortByMessageDsc []*Tracker

func (sb sortByMessageDsc) Len() int { return len(sb) }
func (sb sortByMessageDsc) Swap(i, j int) { sb[i], sb[j] = sb[j], sb[i] }
func (sb sortByMessageDsc) Less(i, j int) bool { return sb[i].Message > sb[j].Message }
func (sb sortByMessageDsc) Less(i, j int) bool { return sb[i].message() > sb[j].message() }

type sortByPercent []*Tracker

Expand Down
9 changes: 9 additions & 0 deletions progress/tracker_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ func TestTracker_IncrementWithError(t *testing.T) {
tracker := Tracker{Total: 100}
assert.Equal(t, int64(0), tracker.value)
assert.Equal(t, int64(100), tracker.Total)
assert.False(t, tracker.IsErrored())

tracker.IncrementWithError(10)
assert.Equal(t, int64(10), tracker.value)
Expand Down Expand Up @@ -175,3 +176,11 @@ func TestTracker_Value(t *testing.T) {
assert.Equal(t, int64(5), tracker.value)
assert.Equal(t, int64(5), tracker.Value())
}

func TestTracker_UpdateMessage(t *testing.T) {
tracker := Tracker{Message: "foo"}
assert.Equal(t, "foo", tracker.message())

tracker.UpdateMessage("bar")
assert.Equal(t, "bar", tracker.message())
}