Skip to content

Commit

Permalink
progress: support an "overall" tracker tracking the full progress (#62)
Browse files Browse the repository at this point in the history
  • Loading branch information
jedib0t committed Aug 23, 2018
1 parent c83e531 commit 5dd3188
Show file tree
Hide file tree
Showing 16 changed files with 427 additions and 205 deletions.
5 changes: 4 additions & 1 deletion Makefile
Expand Up @@ -27,13 +27,16 @@ demo-table:
dep:
dep ensure

fmt:
go fmt $(shell go list ./...)

lint:
golint -set_exit_status $(shell go list ./...)

profile:
sh profile.sh

test: lint vet cyclo
test: fmt lint vet cyclo
go test -cover -coverprofile=.coverprofile $(shell go list ./...)

vet:
Expand Down
27 changes: 15 additions & 12 deletions cmd/demo-progress/demo.go
Expand Up @@ -10,35 +10,35 @@ import (

var (
autoStop = flag.Bool("auto-stop", false, "Auto-stop rendering?")
numTrackers = flag.Int64("num-trackers", 13, "Number of Trackers")
numTrackers = flag.Int("num-trackers", 13, "Number of Trackers")
)

func trackSomething(pw progress.Writer, idx int64) {
total := idx * idx * idx * 250
incrementPerCycle := idx * (*numTrackers) * 250
incrementPerCycle := idx * int64(*numTrackers) * 250

var units progress.Units
var units *progress.Units
switch {
case idx%5 == 0:
units = progress.UnitsCurrencyPound
units = &progress.UnitsCurrencyPound
case idx%4 == 0:
units = progress.UnitsCurrencyDollar
units = &progress.UnitsCurrencyDollar
case idx%3 == 0:
units = progress.UnitsBytes
units = &progress.UnitsBytes
default:
units = progress.UnitsDefault
units = &progress.UnitsDefault
}

var message string
switch units {
case progress.UnitsBytes:
case &progress.UnitsBytes:
message = fmt.Sprintf("Downloading File #%3d", idx)
case progress.UnitsCurrencyDollar, progress.UnitsCurrencyEuro, progress.UnitsCurrencyPound:
case &progress.UnitsCurrencyDollar, &progress.UnitsCurrencyEuro, &progress.UnitsCurrencyPound:
message = fmt.Sprintf("Transferring Amount #%3d", idx)
default:
message = fmt.Sprintf("Calculating Total #%3d", idx)
}
tracker := progress.Tracker{Message: message, Total: total, Units: units}
tracker := progress.Tracker{Message: message, Total: total, Units: *units}

pw.AppendTracker(&tracker)

Expand All @@ -59,11 +59,14 @@ func main() {
pw := progress.NewWriter()
pw.SetAutoStop(*autoStop)
pw.SetTrackerLength(25)
pw.ShowOverallTracker(true)
pw.ShowTime(true)
pw.ShowTracker(true)
pw.ShowValue(true)
pw.SetMessageWidth(24)
pw.SetNumTrackersExpected(*numTrackers)
pw.SetSortBy(progress.SortByPercentDsc)
pw.SetStyle(progress.StyleCircle)
pw.SetStyle(progress.StyleDefault)
pw.SetTrackerPosition(progress.PositionRight)
pw.SetUpdateFrequency(time.Millisecond * 100)
pw.Style().Colors = progress.StyleColorsExample
Expand All @@ -75,7 +78,7 @@ func main() {
// add a bunch of trackers with random parameters to demo most of the
// features available; do this in async too like a client might do (for ex.
// when downloading a bunch of files in parallel)
for idx := int64(1); idx <= *numTrackers; idx++ {
for idx := int64(1); idx <= int64(*numTrackers); idx++ {
go trackSomething(pw, idx)

// in auto-stop mode, the Render logic terminates the moment it detects
Expand Down
31 changes: 31 additions & 0 deletions progress/progress.go
Expand Up @@ -30,7 +30,10 @@ type Progress struct {
hideValue bool
hidePercentage bool
messageWidth int
numTrackersExpected int64
overallTracker *Tracker
renderInProgress bool
showOverallTracker bool
sortBy SortBy
style *Style
trackerPosition Position
Expand Down Expand Up @@ -61,8 +64,18 @@ func (p *Progress) AppendTracker(t *Tracker) {
t.Total = math.MaxInt64
}
t.start()
if p.overallTracker == nil {
p.overallTracker = &Tracker{Total: 1}
if p.numTrackersExpected > 0 {
p.overallTracker.Total = p.numTrackersExpected * 100
}
p.overallTracker.start()
}
p.trackersInQueueMutex.Lock()
p.trackersInQueue = append(p.trackersInQueue, t)
if p.overallTracker.Total < int64(p.Length())*100 {
p.overallTracker.Total = int64(p.Length()) * 100
}
p.trackersInQueueMutex.Unlock()
}

Expand Down Expand Up @@ -104,6 +117,12 @@ func (p *Progress) SetMessageWidth(width int) {
p.messageWidth = width
}

// SetNumTrackersExpected sets the expected number of trackers to be tracked.
// This helps calculate the overall progress with better accuracy.
func (p *Progress) SetNumTrackersExpected(numTrackers int) {
p.numTrackersExpected = int64(numTrackers)
}

// SetOutputWriter redirects the output of Render to an io.writer object like
// os.Stdout or os.Stderr or a file. Warning: redirecting the output to a file
// may not work well as the Render() logic moves the cursor around a lot.
Expand Down Expand Up @@ -145,6 +164,11 @@ func (p *Progress) ShowPercentage(show bool) {
p.hidePercentage = !show
}

// ShowOverallTracker toggles showing the Overall progress tracker.
func (p *Progress) ShowOverallTracker(show bool) {
p.showOverallTracker = show
}

// ShowTime toggles showing the Time taken by each Tracker.
func (p *Progress) ShowTime(show bool) {
p.hideTime = !show
Expand Down Expand Up @@ -204,3 +228,10 @@ func (p *Progress) initForRender() {
p.updateFrequency = DefaultUpdateFrequency
}
}

// renderHint has hints for the Render*() logic
type renderHint struct {
hideTime bool // hide the time
hideValue bool // hide the value
isOverallTracker bool // is the Overall Progress tracker
}
16 changes: 16 additions & 0 deletions progress/progress_test.go
Expand Up @@ -63,6 +63,14 @@ func TestProgress_SetAutoStop(t *testing.T) {
assert.True(t, p.autoStop)
}

func TestProgress_SetNumTrackersExpected(t *testing.T) {
p := Progress{}
assert.Equal(t, int64(0), p.numTrackersExpected)

p.SetNumTrackersExpected(5)
assert.Equal(t, int64(5), p.numTrackersExpected)
}

func TestProgress_SetOutputWriter(t *testing.T) {
p := Progress{}
assert.Nil(t, p.outputWriter)
Expand Down Expand Up @@ -117,6 +125,14 @@ func TestProgress_SetUpdateFrequency(t *testing.T) {
assert.Equal(t, time.Duration(time.Second), p.updateFrequency)
}

func TestProgress_ShowOverallTracker(t *testing.T) {
p := Progress{}
assert.False(t, p.showOverallTracker)

p.ShowOverallTracker(true)
assert.True(t, p.showOverallTracker)
}

func TestProgress_ShowPercentage(t *testing.T) {
p := Progress{}
assert.False(t, p.hidePercentage)
Expand Down

0 comments on commit 5dd3188

Please sign in to comment.