diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index 200cd99259c..0d23329d9e7 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -36,7 +36,7 @@ }, { "ImportPath": "github.com/cheggaaa/pb", - "Rev": "e8c7cc515bfde3e267957a3b110080ceed51354e" + "Rev": "d7729fd7ec1372c15b83db39834bf842bf2d69fb" }, { "ImportPath": "github.com/codahale/hdrhistogram", diff --git a/Godeps/_workspace/src/github.com/cheggaaa/pb/README.md b/Godeps/_workspace/src/github.com/cheggaaa/pb/README.md index 9a6f6b41fa4..af5c4bd50f3 100644 --- a/Godeps/_workspace/src/github.com/cheggaaa/pb/README.md +++ b/Godeps/_workspace/src/github.com/cheggaaa/pb/README.md @@ -58,10 +58,10 @@ bar.ShowTimeLeft = true bar.ShowSpeed = true // sets the width of the progress bar -bar.SetWith(80) +bar.SetWidth(80) // sets the width of the progress bar, but if terminal size smaller will be ignored -bar.SetMaxWith(80) +bar.SetMaxWidth(80) // convert output to readable format (like KB, MB) bar.SetUnits(pb.U_BYTES) diff --git a/Godeps/_workspace/src/github.com/cheggaaa/pb/format.go b/Godeps/_workspace/src/github.com/cheggaaa/pb/format.go index e024e36d40c..1dd210be4b7 100644 --- a/Godeps/_workspace/src/github.com/cheggaaa/pb/format.go +++ b/Godeps/_workspace/src/github.com/cheggaaa/pb/format.go @@ -6,21 +6,24 @@ import ( "strings" ) +type Units int + const ( // By default, without type handle - U_NO = 0 + U_NO Units = iota // Handle as b, Kb, Mb, etc - U_BYTES = 1 + U_BYTES ) // Format integer -func Format(i int64, units int) string { +func Format(i int64, units Units) string { switch units { case U_BYTES: return FormatBytes(i) + default: + // by default just convert to string + return strconv.FormatInt(i, 10) } - // by default just convert to string - return strconv.Itoa(int(i)) } // Convert bytes to human readable string. Like a 2 MB, 64.2 KB, 52 B diff --git a/Godeps/_workspace/src/github.com/cheggaaa/pb/pb.go b/Godeps/_workspace/src/github.com/cheggaaa/pb/pb.go index 01c715720ed..104bd4a60e2 100644 --- a/Godeps/_workspace/src/github.com/cheggaaa/pb/pb.go +++ b/Godeps/_workspace/src/github.com/cheggaaa/pb/pb.go @@ -5,6 +5,7 @@ import ( "io" "math" "strings" + "sync" "sync/atomic" "time" ) @@ -24,13 +25,13 @@ var ( ) // Create new progress bar object -func New(total int) (pb *ProgressBar) { +func New(total int) *ProgressBar { return New64(int64(total)) } // Create new progress bar object uding int64 as total -func New64(total int64) (pb *ProgressBar) { - pb = &ProgressBar{ +func New64(total int64) *ProgressBar { + pb := &ProgressBar{ Total: total, RefreshRate: DEFAULT_REFRESH_RATE, ShowPercent: true, @@ -38,18 +39,17 @@ func New64(total int64) (pb *ProgressBar) { ShowBar: true, ShowTimeLeft: true, ShowFinalTime: true, + Units: U_NO, ManualUpdate: false, + isFinish: make(chan struct{}), currentValue: -1, } - pb.Format(FORMAT) - return + return pb.Format(FORMAT) } // Create new object and start -func StartNew(total int) (pb *ProgressBar) { - pb = New(total) - pb.Start() - return +func StartNew(total int) *ProgressBar { + return New(total).Start() } // Callback for custom output @@ -71,13 +71,16 @@ type ProgressBar struct { Output io.Writer Callback Callback NotPrint bool - Units int + Units Units Width int ForceWidth bool ManualUpdate bool - isFinish bool + finishOnce sync.Once //Guards isFinish + isFinish chan struct{} + startTime time.Time + startValue int64 currentValue int64 prefix, postfix string @@ -90,16 +93,18 @@ type ProgressBar struct { } // Start print -func (pb *ProgressBar) Start() { +func (pb *ProgressBar) Start() *ProgressBar { pb.startTime = time.Now() + pb.startValue = pb.current if pb.Total == 0 { pb.ShowBar = false pb.ShowTimeLeft = false pb.ShowPercent = false - } + } if !pb.ManualUpdate { go pb.writer() } + return pb } // Increment current value @@ -108,8 +113,14 @@ func (pb *ProgressBar) Increment() int { } // Set current value -func (pb *ProgressBar) Set(current int) { - atomic.StoreInt64(&pb.current, int64(current)) +func (pb *ProgressBar) Set(current int) *ProgressBar { + return pb.Set64(int64(current)) +} + +// Set64 sets the current value as int64 +func (pb *ProgressBar) Set64(current int64) *ProgressBar { + atomic.StoreInt64(&pb.current, current) + return pb } // Add to current value @@ -122,75 +133,69 @@ func (pb *ProgressBar) Add64(add int64) int64 { } // Set prefix string -func (pb *ProgressBar) Prefix(prefix string) (bar *ProgressBar) { +func (pb *ProgressBar) Prefix(prefix string) *ProgressBar { pb.prefix = prefix return pb } // Set postfix string -func (pb *ProgressBar) Postfix(postfix string) (bar *ProgressBar) { +func (pb *ProgressBar) Postfix(postfix string) *ProgressBar { pb.postfix = postfix return pb } // Set custom format for bar // Example: bar.Format("[=>_]") -func (pb *ProgressBar) Format(format string) (bar *ProgressBar) { - bar = pb +func (pb *ProgressBar) Format(format string) *ProgressBar { formatEntries := strings.Split(format, "") - if len(formatEntries) != 5 { - return + if len(formatEntries) == 5 { + pb.BarStart = formatEntries[0] + pb.BarEnd = formatEntries[4] + pb.Empty = formatEntries[3] + pb.Current = formatEntries[1] + pb.CurrentN = formatEntries[2] } - pb.BarStart = formatEntries[0] - pb.BarEnd = formatEntries[4] - pb.Empty = formatEntries[3] - pb.Current = formatEntries[1] - pb.CurrentN = formatEntries[2] - return + return pb } // Set bar refresh rate -func (pb *ProgressBar) SetRefreshRate(rate time.Duration) (bar *ProgressBar) { - bar = pb +func (pb *ProgressBar) SetRefreshRate(rate time.Duration) *ProgressBar { pb.RefreshRate = rate - return + return pb } // Set units // bar.SetUnits(U_NO) - by default // bar.SetUnits(U_BYTES) - for Mb, Kb, etc -func (pb *ProgressBar) SetUnits(units int) (bar *ProgressBar) { - bar = pb - switch units { - case U_NO, U_BYTES: - pb.Units = units - } - return +func (pb *ProgressBar) SetUnits(units Units) *ProgressBar { + pb.Units = units + return pb } // Set max width, if width is bigger than terminal width, will be ignored -func (pb *ProgressBar) SetMaxWidth(width int) (bar *ProgressBar) { - bar = pb +func (pb *ProgressBar) SetMaxWidth(width int) *ProgressBar { pb.Width = width pb.ForceWidth = false - return + return pb } // Set bar width -func (pb *ProgressBar) SetWidth(width int) (bar *ProgressBar) { - bar = pb +func (pb *ProgressBar) SetWidth(width int) *ProgressBar { pb.Width = width pb.ForceWidth = true - return + return pb } // End print func (pb *ProgressBar) Finish() { - pb.isFinish = true - pb.write(atomic.LoadInt64(&pb.current)) - if !pb.NotPrint { - fmt.Println() - } + //Protect multiple calls + pb.finishOnce.Do(func() { + close(pb.isFinish) + pb.write(atomic.LoadInt64(&pb.current)) + if !pb.NotPrint { + fmt.Println() + } + }) } // End print and write string 'str' @@ -228,7 +233,7 @@ func (pb *ProgressBar) write(current int64) { percent := float64(current) / (float64(pb.Total) / float64(100)) percentBox = fmt.Sprintf(" %#.02f %% ", percent) } - + // counters if pb.ShowCounters { if pb.Total > 0 { @@ -240,22 +245,26 @@ func (pb *ProgressBar) write(current int64) { // time left fromStart := time.Now().Sub(pb.startTime) - if pb.isFinish { + currentFromStart := current - pb.startValue + select { + case <-pb.isFinish: if pb.ShowFinalTime { left := (fromStart / time.Second) * time.Second timeLeftBox = left.String() } - } else if pb.ShowTimeLeft && current > 0 { - perEntry := fromStart / time.Duration(current) - left := time.Duration(pb.Total-current) * perEntry - left = (left / time.Second) * time.Second - timeLeftBox = left.String() + default: + if pb.ShowTimeLeft && currentFromStart > 0 { + perEntry := fromStart / time.Duration(currentFromStart) + left := time.Duration(pb.Total-currentFromStart) * perEntry + left = (left / time.Second) * time.Second + timeLeftBox = left.String() + } } // speed - if pb.ShowSpeed && current > 0 { + if pb.ShowSpeed && currentFromStart > 0 { fromStart := time.Now().Sub(pb.startTime) - speed := float64(current) / (float64(fromStart) / float64(time.Second)) + speed := float64(currentFromStart) / (float64(fromStart) / float64(time.Second)) speedBox = Format(int64(speed), pb.Units) + "/s " } @@ -324,12 +333,14 @@ func (pb *ProgressBar) Update() { // Internal loop for writing progressbar func (pb *ProgressBar) writer() { + pb.Update() for { - if pb.isFinish { - break + select { + case <-pb.isFinish: + return + case <-time.After(pb.RefreshRate): + pb.Update() } - pb.Update() - time.Sleep(pb.RefreshRate) } } diff --git a/Godeps/_workspace/src/github.com/cheggaaa/pb/pb_nix.go b/Godeps/_workspace/src/github.com/cheggaaa/pb/pb_nix.go index 75f9ba31469..5db4e523fc4 100644 --- a/Godeps/_workspace/src/github.com/cheggaaa/pb/pb_nix.go +++ b/Godeps/_workspace/src/github.com/cheggaaa/pb/pb_nix.go @@ -1,4 +1,4 @@ -// +build linux darwin freebsd openbsd +// +build linux darwin freebsd netbsd openbsd package pb diff --git a/Godeps/_workspace/src/github.com/cheggaaa/pb/pb_test.go b/Godeps/_workspace/src/github.com/cheggaaa/pb/pb_test.go index 75783d63089..dfe394fd4bb 100644 --- a/Godeps/_workspace/src/github.com/cheggaaa/pb/pb_test.go +++ b/Godeps/_workspace/src/github.com/cheggaaa/pb/pb_test.go @@ -28,3 +28,10 @@ func Test_Width(t *testing.T) { bar.Increment() bar.Finish() } + +func Test_MultipleFinish(t *testing.T) { + bar := New(5000) + bar.Add(2000) + bar.Finish() + bar.Finish() +} diff --git a/Godeps/_workspace/src/github.com/cheggaaa/pb/pb_x.go b/Godeps/_workspace/src/github.com/cheggaaa/pb/pb_x.go index b630e592f11..dd5f906e186 100644 --- a/Godeps/_workspace/src/github.com/cheggaaa/pb/pb_x.go +++ b/Godeps/_workspace/src/github.com/cheggaaa/pb/pb_x.go @@ -1,4 +1,4 @@ -// +build linux darwin freebsd openbsd solaris +// +build linux darwin freebsd netbsd openbsd solaris package pb