summaryrefslogtreecommitdiff
path: root/vendor/gopkg.in/cheggaaa
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/gopkg.in/cheggaaa')
-rw-r--r--vendor/gopkg.in/cheggaaa/pb.v1/README.md11
-rw-r--r--vendor/gopkg.in/cheggaaa/pb.v1/format.go84
-rw-r--r--vendor/gopkg.in/cheggaaa/pb.v1/pb.go193
-rw-r--r--vendor/gopkg.in/cheggaaa/pb.v1/pb_appengine.go2
-rw-r--r--vendor/gopkg.in/cheggaaa/pb.v1/pb_nix.go8
-rw-r--r--vendor/gopkg.in/cheggaaa/pb.v1/pb_solaris.go6
-rw-r--r--vendor/gopkg.in/cheggaaa/pb.v1/pb_win.go4
-rw-r--r--vendor/gopkg.in/cheggaaa/pb.v1/pb_x.go118
-rw-r--r--vendor/gopkg.in/cheggaaa/pb.v1/pool.go62
-rw-r--r--vendor/gopkg.in/cheggaaa/pb.v1/pool_win.go16
-rw-r--r--vendor/gopkg.in/cheggaaa/pb.v1/pool_x.go13
-rw-r--r--vendor/gopkg.in/cheggaaa/pb.v1/runecount.go2
-rw-r--r--vendor/gopkg.in/cheggaaa/pb.v1/termios_nix.go7
-rw-r--r--vendor/gopkg.in/cheggaaa/pb.v1/termios_sysv.go13
14 files changed, 342 insertions, 197 deletions
diff --git a/vendor/gopkg.in/cheggaaa/pb.v1/README.md b/vendor/gopkg.in/cheggaaa/pb.v1/README.md
index 31babb305..1295df70e 100644
--- a/vendor/gopkg.in/cheggaaa/pb.v1/README.md
+++ b/vendor/gopkg.in/cheggaaa/pb.v1/README.md
@@ -1,7 +1,8 @@
# Terminal progress bar for Go
-Simple progress bar for console programs.
-
+Simple progress bar for console programs.
+
+Please check the new version https://github.com/cheggaaa/pb/tree/v2 (currently, it's beta)
## Installation
@@ -170,7 +171,7 @@ The result will be as follows:
```
$ go run example/multiple.go
-First 141 / 1000 [===============>---------------------------------------] 14.10 % 44s
-Second 139 / 1000 [==============>---------------------------------------] 13.90 % 44s
-Third 152 / 1000 [================>--------------------------------------] 15.20 % 40s
+First 34 / 200 [=========>---------------------------------------------] 17.00% 00m08s
+Second 42 / 200 [===========>------------------------------------------] 21.00% 00m06s
+Third 36 / 200 [=========>---------------------------------------------] 18.00% 00m08s
```
diff --git a/vendor/gopkg.in/cheggaaa/pb.v1/format.go b/vendor/gopkg.in/cheggaaa/pb.v1/format.go
index d5aeff793..8bb8a7a1d 100644
--- a/vendor/gopkg.in/cheggaaa/pb.v1/format.go
+++ b/vendor/gopkg.in/cheggaaa/pb.v1/format.go
@@ -2,7 +2,6 @@ package pb
import (
"fmt"
- "strings"
"time"
)
@@ -11,12 +10,26 @@ type Units int
const (
// U_NO are default units, they represent a simple value and are not formatted at all.
U_NO Units = iota
- // U_BYTES units are formatted in a human readable way (b, Bb, Mb, ...)
+ // U_BYTES units are formatted in a human readable way (B, KiB, MiB, ...)
U_BYTES
+ // U_BYTES_DEC units are like U_BYTES, but base 10 (B, KB, MB, ...)
+ U_BYTES_DEC
// U_DURATION units are formatted in a human readable way (3h14m15s)
U_DURATION
)
+const (
+ KiB = 1024
+ MiB = 1048576
+ GiB = 1073741824
+ TiB = 1099511627776
+
+ KB = 1e3
+ MB = 1e6
+ GB = 1e9
+ TB = 1e12
+)
+
func Format(i int64) *formatter {
return &formatter{n: i}
}
@@ -28,11 +41,6 @@ type formatter struct {
perSec bool
}
-func (f *formatter) Value(n int64) *formatter {
- f.n = n
- return f
-}
-
func (f *formatter) To(unit Units) *formatter {
f.unit = unit
return f
@@ -52,13 +60,10 @@ func (f *formatter) String() (out string) {
switch f.unit {
case U_BYTES:
out = formatBytes(f.n)
+ case U_BYTES_DEC:
+ out = formatBytesDec(f.n)
case U_DURATION:
- d := time.Duration(f.n)
- if d > time.Hour*24 {
- out = fmt.Sprintf("%dd", d/24/time.Hour)
- d -= (d / time.Hour / 24) * (time.Hour * 24)
- }
- out = fmt.Sprintf("%s%v", out, d)
+ out = formatDuration(f.n)
default:
out = fmt.Sprintf(fmt.Sprintf("%%%dd", f.width), f.n)
}
@@ -68,20 +73,53 @@ func (f *formatter) String() (out string) {
return
}
-// Convert bytes to human readable string. Like a 2 MB, 64.2 KB, 52 B
+// Convert bytes to human readable string. Like 2 MiB, 64.2 KiB, 52 B
func formatBytes(i int64) (result string) {
switch {
- case i > (1024 * 1024 * 1024 * 1024):
- result = fmt.Sprintf("%.02f TB", float64(i)/1024/1024/1024/1024)
- case i > (1024 * 1024 * 1024):
- result = fmt.Sprintf("%.02f GB", float64(i)/1024/1024/1024)
- case i > (1024 * 1024):
- result = fmt.Sprintf("%.02f MB", float64(i)/1024/1024)
- case i > 1024:
- result = fmt.Sprintf("%.02f KB", float64(i)/1024)
+ case i >= TiB:
+ result = fmt.Sprintf("%.02f TiB", float64(i)/TiB)
+ case i >= GiB:
+ result = fmt.Sprintf("%.02f GiB", float64(i)/GiB)
+ case i >= MiB:
+ result = fmt.Sprintf("%.02f MiB", float64(i)/MiB)
+ case i >= KiB:
+ result = fmt.Sprintf("%.02f KiB", float64(i)/KiB)
default:
result = fmt.Sprintf("%d B", i)
}
- result = strings.Trim(result, " ")
+ return
+}
+
+// Convert bytes to base-10 human readable string. Like 2 MB, 64.2 KB, 52 B
+func formatBytesDec(i int64) (result string) {
+ switch {
+ case i >= TB:
+ result = fmt.Sprintf("%.02f TB", float64(i)/TB)
+ case i >= GB:
+ result = fmt.Sprintf("%.02f GB", float64(i)/GB)
+ case i >= MB:
+ result = fmt.Sprintf("%.02f MB", float64(i)/MB)
+ case i >= KB:
+ result = fmt.Sprintf("%.02f KB", float64(i)/KB)
+ default:
+ result = fmt.Sprintf("%d B", i)
+ }
+ return
+}
+
+func formatDuration(n int64) (result string) {
+ d := time.Duration(n)
+ if d > time.Hour*24 {
+ result = fmt.Sprintf("%dd", d/24/time.Hour)
+ d -= (d / time.Hour / 24) * (time.Hour * 24)
+ }
+ if d > time.Hour {
+ result = fmt.Sprintf("%s%dh", result, d/time.Hour)
+ d -= d / time.Hour * time.Hour
+ }
+ m := d / time.Minute
+ d -= m * time.Minute
+ s := d / time.Second
+ result = fmt.Sprintf("%s%02dm%02ds", result, m, s)
return
}
diff --git a/vendor/gopkg.in/cheggaaa/pb.v1/pb.go b/vendor/gopkg.in/cheggaaa/pb.v1/pb.go
index f1f15bff3..e03291b89 100644
--- a/vendor/gopkg.in/cheggaaa/pb.v1/pb.go
+++ b/vendor/gopkg.in/cheggaaa/pb.v1/pb.go
@@ -13,7 +13,7 @@ import (
)
// Current version
-const Version = "1.0.6"
+const Version = "1.0.27"
const (
// Default refresh rate - 200ms
@@ -37,18 +37,17 @@ func New(total int) *ProgressBar {
// Create new progress bar object using int64 as total
func New64(total int64) *ProgressBar {
pb := &ProgressBar{
- Total: total,
- RefreshRate: DEFAULT_REFRESH_RATE,
- ShowPercent: true,
- ShowCounters: true,
- ShowBar: true,
- ShowTimeLeft: true,
- ShowFinalTime: true,
- Units: U_NO,
- ManualUpdate: false,
- finish: make(chan struct{}),
- currentValue: -1,
- mu: new(sync.Mutex),
+ Total: total,
+ RefreshRate: DEFAULT_REFRESH_RATE,
+ ShowPercent: true,
+ ShowCounters: true,
+ ShowBar: true,
+ ShowTimeLeft: true,
+ ShowElapsedTime: false,
+ ShowFinalTime: true,
+ Units: U_NO,
+ ManualUpdate: false,
+ finish: make(chan struct{}),
}
return pb.Format(FORMAT)
}
@@ -67,13 +66,14 @@ func StartNew(total int) *ProgressBar {
type Callback func(out string)
type ProgressBar struct {
- current int64 // current must be first member of struct (https://code.google.com/p/go/issues/detail?id=5278)
+ current int64 // current must be first member of struct (https://code.google.com/p/go/issues/detail?id=5278)
+ previous int64
Total int64
RefreshRate time.Duration
ShowPercent, ShowCounters bool
ShowSpeed, ShowTimeLeft, ShowBar bool
- ShowFinalTime bool
+ ShowFinalTime, ShowElapsedTime bool
Output io.Writer
Callback Callback
NotPrint bool
@@ -91,13 +91,14 @@ type ProgressBar struct {
finish chan struct{}
isFinish bool
- startTime time.Time
- startValue int64
- currentValue int64
+ startTime time.Time
+ startValue int64
+
+ changeTime time.Time
prefix, postfix string
- mu *sync.Mutex
+ mu sync.Mutex
lastPrint string
BarStart string
@@ -112,8 +113,8 @@ type ProgressBar struct {
// Start print
func (pb *ProgressBar) Start() *ProgressBar {
pb.startTime = time.Now()
- pb.startValue = pb.current
- if pb.Total == 0 {
+ pb.startValue = atomic.LoadInt64(&pb.current)
+ if atomic.LoadInt64(&pb.Total) == 0 {
pb.ShowTimeLeft = false
pb.ShowPercent = false
pb.AutoStat = false
@@ -158,12 +159,16 @@ func (pb *ProgressBar) Add64(add int64) int64 {
// Set prefix string
func (pb *ProgressBar) Prefix(prefix string) *ProgressBar {
+ pb.mu.Lock()
+ defer pb.mu.Unlock()
pb.prefix = prefix
return pb
}
// Set postfix string
func (pb *ProgressBar) Postfix(postfix string) *ProgressBar {
+ pb.mu.Lock()
+ defer pb.mu.Unlock()
pb.postfix = postfix
return pb
}
@@ -173,7 +178,7 @@ func (pb *ProgressBar) Postfix(postfix string) *ProgressBar {
// Example: bar.Format("[\x00=\x00>\x00-\x00]") // \x00 is the delimiter
func (pb *ProgressBar) Format(format string) *ProgressBar {
var formatEntries []string
- if len(format) == 5 {
+ if utf8.RuneCountInString(format) == 5 {
formatEntries = strings.Split(format, "")
} else {
formatEntries = strings.Split(format, "\x00")
@@ -221,7 +226,9 @@ func (pb *ProgressBar) Finish() {
//Protect multiple calls
pb.finishOnce.Do(func() {
close(pb.finish)
- pb.write(atomic.LoadInt64(&pb.current))
+ pb.write(atomic.LoadInt64(&pb.Total), atomic.LoadInt64(&pb.current))
+ pb.mu.Lock()
+ defer pb.mu.Unlock()
switch {
case pb.Output != nil:
fmt.Fprintln(pb.Output)
@@ -232,6 +239,13 @@ func (pb *ProgressBar) Finish() {
})
}
+// IsFinished return boolean
+func (pb *ProgressBar) IsFinished() bool {
+ pb.mu.Lock()
+ defer pb.mu.Unlock()
+ return pb.isFinish
+}
+
// End print and write string 'str'
func (pb *ProgressBar) FinishPrint(str string) {
pb.Finish()
@@ -262,16 +276,18 @@ func (pb *ProgressBar) NewProxyReader(r io.Reader) *Reader {
return &Reader{r, pb}
}
-func (pb *ProgressBar) write(current int64) {
+func (pb *ProgressBar) write(total, current int64) {
+ pb.mu.Lock()
+ defer pb.mu.Unlock()
width := pb.GetWidth()
- var percentBox, countersBox, timeLeftBox, speedBox, barBox, end, out string
+ var percentBox, countersBox, timeLeftBox, timeSpentBox, speedBox, barBox, end, out string
// percents
if pb.ShowPercent {
var percent float64
- if pb.Total > 0 {
- percent = float64(current) / (float64(pb.Total) / float64(100))
+ if total > 0 {
+ percent = float64(current) / (float64(total) / float64(100))
} else {
percent = float64(current) / float64(100)
}
@@ -281,17 +297,24 @@ func (pb *ProgressBar) write(current int64) {
// counters
if pb.ShowCounters {
current := Format(current).To(pb.Units).Width(pb.UnitsWidth)
- if pb.Total > 0 {
- total := Format(pb.Total).To(pb.Units).Width(pb.UnitsWidth)
- countersBox = fmt.Sprintf(" %s / %s ", current, total)
+ if total > 0 {
+ totalS := Format(total).To(pb.Units).Width(pb.UnitsWidth)
+ countersBox = fmt.Sprintf(" %s / %s ", current, totalS)
} else {
countersBox = fmt.Sprintf(" %s / ? ", current)
}
}
// time left
- fromStart := time.Now().Sub(pb.startTime)
currentFromStart := current - pb.startValue
+ fromStart := time.Now().Sub(pb.startTime)
+ lastChangeTime := pb.changeTime
+ fromChange := lastChangeTime.Sub(pb.startTime)
+
+ if pb.ShowElapsedTime {
+ timeSpentBox = fmt.Sprintf(" %s ", (fromStart/time.Second)*time.Second)
+ }
+
select {
case <-pb.finish:
if pb.ShowFinalTime {
@@ -301,17 +324,20 @@ func (pb *ProgressBar) write(current int64) {
}
default:
if pb.ShowTimeLeft && currentFromStart > 0 {
- perEntry := fromStart / time.Duration(currentFromStart)
+ perEntry := fromChange / time.Duration(currentFromStart)
var left time.Duration
- if pb.Total > 0 {
- left = time.Duration(pb.Total-currentFromStart) * perEntry
+ if total > 0 {
+ left = time.Duration(total-currentFromStart) * perEntry
+ left -= time.Since(lastChangeTime)
left = (left / time.Second) * time.Second
} else {
left = time.Duration(currentFromStart) * perEntry
left = (left / time.Second) * time.Second
}
- timeLeft := Format(int64(left)).To(U_DURATION).String()
- timeLeftBox = fmt.Sprintf(" %s", timeLeft)
+ if left > 0 {
+ timeLeft := Format(int64(left)).To(U_DURATION).String()
+ timeLeftBox = fmt.Sprintf(" %s", timeLeft)
+ }
}
}
@@ -326,30 +352,38 @@ func (pb *ProgressBar) write(current int64) {
speedBox = " " + Format(int64(speed)).To(pb.Units).Width(pb.UnitsWidth).PerSec().String()
}
- barWidth := escapeAwareRuneCountInString(countersBox + pb.BarStart + pb.BarEnd + percentBox + timeLeftBox + speedBox + pb.prefix + pb.postfix)
+ barWidth := escapeAwareRuneCountInString(countersBox + pb.BarStart + pb.BarEnd + percentBox + timeSpentBox + timeLeftBox + speedBox + pb.prefix + pb.postfix)
// bar
if pb.ShowBar {
size := width - barWidth
if size > 0 {
- if pb.Total > 0 {
- curCount := int(math.Ceil((float64(current) / float64(pb.Total)) * float64(size)))
- emptCount := size - curCount
+ if total > 0 {
+ curSize := int(math.Ceil((float64(current) / float64(total)) * float64(size)))
+ emptySize := size - curSize
barBox = pb.BarStart
- if emptCount < 0 {
- emptCount = 0
+ if emptySize < 0 {
+ emptySize = 0
}
- if curCount > size {
- curCount = size
+ if curSize > size {
+ curSize = size
}
- if emptCount <= 0 {
- barBox += strings.Repeat(pb.Current, curCount)
- } else if curCount > 0 {
- barBox += strings.Repeat(pb.Current, curCount-1) + pb.CurrentN
+
+ cursorLen := escapeAwareRuneCountInString(pb.Current)
+ if emptySize <= 0 {
+ barBox += strings.Repeat(pb.Current, curSize/cursorLen)
+ } else if curSize > 0 {
+ cursorEndLen := escapeAwareRuneCountInString(pb.CurrentN)
+ cursorRepetitions := (curSize - cursorEndLen) / cursorLen
+ barBox += strings.Repeat(pb.Current, cursorRepetitions)
+ barBox += pb.CurrentN
}
- barBox += strings.Repeat(pb.Empty, emptCount) + pb.BarEnd
+
+ emptyLen := escapeAwareRuneCountInString(pb.Empty)
+ barBox += strings.Repeat(pb.Empty, emptySize/emptyLen)
+ barBox += pb.BarEnd
} else {
- barBox = pb.BarStart
pos := size - int(current)%int(size)
+ barBox = pb.BarStart
if pos-1 > 0 {
barBox += strings.Repeat(pb.Empty, pos-1)
}
@@ -363,17 +397,18 @@ func (pb *ProgressBar) write(current int64) {
}
// check len
- out = pb.prefix + countersBox + barBox + percentBox + speedBox + timeLeftBox + pb.postfix
- if escapeAwareRuneCountInString(out) < width {
- end = strings.Repeat(" ", width-utf8.RuneCountInString(out))
+ out = pb.prefix + timeSpentBox + countersBox + barBox + percentBox + speedBox + timeLeftBox + pb.postfix
+
+ if cl := escapeAwareRuneCountInString(out); cl < width {
+ end = strings.Repeat(" ", width-cl)
}
// and print!
- pb.mu.Lock()
pb.lastPrint = out + end
- pb.mu.Unlock()
+ isFinish := pb.isFinish
+
switch {
- case pb.isFinish:
+ case isFinish:
return
case pb.Output != nil:
fmt.Fprint(pb.Output, "\r"+out+end)
@@ -406,24 +441,55 @@ func (pb *ProgressBar) GetWidth() int {
// Write the current state of the progressbar
func (pb *ProgressBar) Update() {
c := atomic.LoadInt64(&pb.current)
- if pb.AlwaysUpdate || c != pb.currentValue {
- pb.write(c)
- pb.currentValue = c
+ p := atomic.LoadInt64(&pb.previous)
+ t := atomic.LoadInt64(&pb.Total)
+ if p != c {
+ pb.mu.Lock()
+ pb.changeTime = time.Now()
+ pb.mu.Unlock()
+ atomic.StoreInt64(&pb.previous, c)
}
+ pb.write(t, c)
if pb.AutoStat {
if c == 0 {
pb.startTime = time.Now()
pb.startValue = 0
- } else if c >= pb.Total && pb.isFinish != true {
+ } else if c >= t && pb.isFinish != true {
pb.Finish()
}
}
}
+// String return the last bar print
func (pb *ProgressBar) String() string {
+ pb.mu.Lock()
+ defer pb.mu.Unlock()
return pb.lastPrint
}
+// SetTotal atomically sets new total count
+func (pb *ProgressBar) SetTotal(total int) *ProgressBar {
+ return pb.SetTotal64(int64(total))
+}
+
+// SetTotal64 atomically sets new total count
+func (pb *ProgressBar) SetTotal64(total int64) *ProgressBar {
+ atomic.StoreInt64(&pb.Total, total)
+ return pb
+}
+
+// Reset bar and set new total count
+// Does effect only on finished bar
+func (pb *ProgressBar) Reset(total int) *ProgressBar {
+ pb.mu.Lock()
+ defer pb.mu.Unlock()
+ if pb.isFinish {
+ pb.SetTotal(total).Set(0)
+ atomic.StoreInt64(&pb.previous, 0)
+ }
+ return pb
+}
+
// Internal loop for refreshing the progressbar
func (pb *ProgressBar) refresher() {
for {
@@ -435,10 +501,3 @@ func (pb *ProgressBar) refresher() {
}
}
}
-
-type window struct {
- Row uint16
- Col uint16
- Xpixel uint16
- Ypixel uint16
-}
diff --git a/vendor/gopkg.in/cheggaaa/pb.v1/pb_appengine.go b/vendor/gopkg.in/cheggaaa/pb.v1/pb_appengine.go
index d85dbc3b2..17168f39a 100644
--- a/vendor/gopkg.in/cheggaaa/pb.v1/pb_appengine.go
+++ b/vendor/gopkg.in/cheggaaa/pb.v1/pb_appengine.go
@@ -1,4 +1,4 @@
-// +build appengine
+// +build appengine js
package pb
diff --git a/vendor/gopkg.in/cheggaaa/pb.v1/pb_nix.go b/vendor/gopkg.in/cheggaaa/pb.v1/pb_nix.go
deleted file mode 100644
index c06097b43..000000000
--- a/vendor/gopkg.in/cheggaaa/pb.v1/pb_nix.go
+++ /dev/null
@@ -1,8 +0,0 @@
-// +build linux darwin freebsd netbsd openbsd dragonfly
-// +build !appengine
-
-package pb
-
-import "syscall"
-
-const sysIoctl = syscall.SYS_IOCTL
diff --git a/vendor/gopkg.in/cheggaaa/pb.v1/pb_solaris.go b/vendor/gopkg.in/cheggaaa/pb.v1/pb_solaris.go
deleted file mode 100644
index b7d461e17..000000000
--- a/vendor/gopkg.in/cheggaaa/pb.v1/pb_solaris.go
+++ /dev/null
@@ -1,6 +0,0 @@
-// +build solaris
-// +build !appengine
-
-package pb
-
-const sysIoctl = 54
diff --git a/vendor/gopkg.in/cheggaaa/pb.v1/pb_win.go b/vendor/gopkg.in/cheggaaa/pb.v1/pb_win.go
index 72f682835..9595e8236 100644
--- a/vendor/gopkg.in/cheggaaa/pb.v1/pb_win.go
+++ b/vendor/gopkg.in/cheggaaa/pb.v1/pb_win.go
@@ -102,7 +102,7 @@ var echoLockMutex sync.Mutex
var oldState word
-func lockEcho() (quit chan int, err error) {
+func lockEcho() (shutdownCh chan struct{}, err error) {
echoLockMutex.Lock()
defer echoLockMutex.Unlock()
if echoLocked {
@@ -124,6 +124,8 @@ func lockEcho() (quit chan int, err error) {
err = fmt.Errorf("Can't set terminal settings: %v", e)
return
}
+
+ shutdownCh = make(chan struct{})
return
}
diff --git a/vendor/gopkg.in/cheggaaa/pb.v1/pb_x.go b/vendor/gopkg.in/cheggaaa/pb.v1/pb_x.go
index 12e6fe6e2..af4251760 100644
--- a/vendor/gopkg.in/cheggaaa/pb.v1/pb_x.go
+++ b/vendor/gopkg.in/cheggaaa/pb.v1/pb_x.go
@@ -1,5 +1,5 @@
// +build linux darwin freebsd netbsd openbsd solaris dragonfly
-// +build !appengine
+// +build !appengine !js
package pb
@@ -8,101 +8,109 @@ import (
"fmt"
"os"
"os/signal"
- "runtime"
"sync"
"syscall"
- "unsafe"
-)
-const (
- TIOCGWINSZ = 0x5413
- TIOCGWINSZ_OSX = 1074295912
+ "golang.org/x/sys/unix"
)
-var tty *os.File
-
var ErrPoolWasStarted = errors.New("Bar pool was started")
-var echoLocked bool
-var echoLockMutex sync.Mutex
+var (
+ echoLockMutex sync.Mutex
+ origTermStatePtr *unix.Termios
+ tty *os.File
+ istty bool
+)
func init() {
+ echoLockMutex.Lock()
+ defer echoLockMutex.Unlock()
+
var err error
tty, err = os.Open("/dev/tty")
+ istty = true
if err != nil {
tty = os.Stdin
+ istty = false
}
}
// terminalWidth returns width of the terminal.
func terminalWidth() (int, error) {
- w := new(window)
- tio := syscall.TIOCGWINSZ
- if runtime.GOOS == "darwin" {
- tio = TIOCGWINSZ_OSX
+ if !istty {
+ return 0, errors.New("Not Supported")
}
- res, _, err := syscall.Syscall(sysIoctl,
- tty.Fd(),
- uintptr(tio),
- uintptr(unsafe.Pointer(w)),
- )
- if int(res) == -1 {
+ echoLockMutex.Lock()
+ defer echoLockMutex.Unlock()
+
+ fd := int(tty.Fd())
+
+ ws, err := unix.IoctlGetWinsize(fd, unix.TIOCGWINSZ)
+ if err != nil {
return 0, err
}
- return int(w.Col), nil
-}
-var oldState syscall.Termios
+ return int(ws.Col), nil
+}
-func lockEcho() (quit chan int, err error) {
+func lockEcho() (shutdownCh chan struct{}, err error) {
echoLockMutex.Lock()
defer echoLockMutex.Unlock()
- if echoLocked {
- err = ErrPoolWasStarted
- return
- }
- echoLocked = true
+ if istty {
+ if origTermStatePtr != nil {
+ return shutdownCh, ErrPoolWasStarted
+ }
- fd := tty.Fd()
- if _, _, e := syscall.Syscall6(sysIoctl, fd, ioctlReadTermios, uintptr(unsafe.Pointer(&oldState)), 0, 0, 0); e != 0 {
- err = fmt.Errorf("Can't get terminal settings: %v", e)
- return
- }
+ fd := int(tty.Fd())
+
+ origTermStatePtr, err = unix.IoctlGetTermios(fd, ioctlReadTermios)
+ if err != nil {
+ return nil, fmt.Errorf("Can't get terminal settings: %v", err)
+ }
+
+ oldTermios := *origTermStatePtr
+ newTermios := oldTermios
+ newTermios.Lflag &^= syscall.ECHO
+ newTermios.Lflag |= syscall.ICANON | syscall.ISIG
+ newTermios.Iflag |= syscall.ICRNL
+ if err := unix.IoctlSetTermios(fd, ioctlWriteTermios, &newTermios); err != nil {
+ return nil, fmt.Errorf("Can't set terminal settings: %v", err)
+ }
- newState := oldState
- newState.Lflag &^= syscall.ECHO
- newState.Lflag |= syscall.ICANON | syscall.ISIG
- newState.Iflag |= syscall.ICRNL
- if _, _, e := syscall.Syscall6(sysIoctl, fd, ioctlWriteTermios, uintptr(unsafe.Pointer(&newState)), 0, 0, 0); e != 0 {
- err = fmt.Errorf("Can't set terminal settings: %v", e)
- return
}
- quit = make(chan int, 1)
- go catchTerminate(quit)
+ shutdownCh = make(chan struct{})
+ go catchTerminate(shutdownCh)
return
}
-func unlockEcho() (err error) {
+func unlockEcho() error {
echoLockMutex.Lock()
defer echoLockMutex.Unlock()
- if !echoLocked {
- return
- }
- echoLocked = false
- fd := tty.Fd()
- if _, _, e := syscall.Syscall6(sysIoctl, fd, ioctlWriteTermios, uintptr(unsafe.Pointer(&oldState)), 0, 0, 0); e != 0 {
- err = fmt.Errorf("Can't set terminal settings")
+ if istty {
+ if origTermStatePtr == nil {
+ return nil
+ }
+
+ fd := int(tty.Fd())
+
+ if err := unix.IoctlSetTermios(fd, ioctlWriteTermios, origTermStatePtr); err != nil {
+ return fmt.Errorf("Can't set terminal settings: %v", err)
+ }
+
}
- return
+ origTermStatePtr = nil
+
+ return nil
}
// listen exit signals and restore terminal state
-func catchTerminate(quit chan int) {
+func catchTerminate(shutdownCh chan struct{}) {
sig := make(chan os.Signal, 1)
signal.Notify(sig, os.Interrupt, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGKILL)
defer signal.Stop(sig)
select {
- case <-quit:
+ case <-shutdownCh:
unlockEcho()
case <-sig:
unlockEcho()
diff --git a/vendor/gopkg.in/cheggaaa/pb.v1/pool.go b/vendor/gopkg.in/cheggaaa/pb.v1/pool.go
index 0b4a4afa8..392e7599c 100644
--- a/vendor/gopkg.in/cheggaaa/pb.v1/pool.go
+++ b/vendor/gopkg.in/cheggaaa/pb.v1/pool.go
@@ -3,6 +3,7 @@
package pb
import (
+ "io"
"sync"
"time"
)
@@ -11,22 +12,36 @@ import (
// You need call pool.Stop() after work
func StartPool(pbs ...*ProgressBar) (pool *Pool, err error) {
pool = new(Pool)
- if err = pool.start(); err != nil {
+ if err = pool.Start(); err != nil {
return
}
pool.Add(pbs...)
return
}
+// NewPool initialises a pool with progress bars, but
+// doesn't start it. You need to call Start manually
+func NewPool(pbs ...*ProgressBar) (pool *Pool) {
+ pool = new(Pool)
+ pool.Add(pbs...)
+ return
+}
+
type Pool struct {
- RefreshRate time.Duration
- bars []*ProgressBar
- quit chan int
- finishOnce sync.Once
+ Output io.Writer
+ RefreshRate time.Duration
+ bars []*ProgressBar
+ lastBarsCount int
+ shutdownCh chan struct{}
+ workerCh chan struct{}
+ m sync.Mutex
+ finishOnce sync.Once
}
// Add progress bars.
func (p *Pool) Add(pbs ...*ProgressBar) {
+ p.m.Lock()
+ defer p.m.Unlock()
for _, bar := range pbs {
bar.ManualUpdate = true
bar.NotPrint = true
@@ -35,30 +50,38 @@ func (p *Pool) Add(pbs ...*ProgressBar) {
}
}
-func (p *Pool) start() (err error) {
+func (p *Pool) Start() (err error) {
p.RefreshRate = DefaultRefreshRate
- quit, err := lockEcho()
+ p.shutdownCh, err = lockEcho()
if err != nil {
return
}
- p.quit = make(chan int)
- go p.writer(quit)
+ p.workerCh = make(chan struct{})
+ go p.writer()
return
}
-func (p *Pool) writer(finish chan int) {
+func (p *Pool) writer() {
var first = true
+ defer func() {
+ if first == false {
+ p.print(false)
+ } else {
+ p.print(true)
+ p.print(false)
+ }
+ close(p.workerCh)
+ }()
+
for {
select {
case <-time.After(p.RefreshRate):
if p.print(first) {
p.print(false)
- finish <- 1
return
}
first = false
- case <-p.quit:
- finish <- 1
+ case <-p.shutdownCh:
return
}
}
@@ -66,11 +89,16 @@ func (p *Pool) writer(finish chan int) {
// Restore terminal state and close pool
func (p *Pool) Stop() error {
- // Wait until one final refresh has passed.
- time.Sleep(p.RefreshRate)
-
p.finishOnce.Do(func() {
- close(p.quit)
+ if p.shutdownCh != nil {
+ close(p.shutdownCh)
+ }
})
+
+ // Wait for the worker to complete
+ select {
+ case <-p.workerCh:
+ }
+
return unlockEcho()
}
diff --git a/vendor/gopkg.in/cheggaaa/pb.v1/pool_win.go b/vendor/gopkg.in/cheggaaa/pb.v1/pool_win.go
index d7a5ace41..63598d378 100644
--- a/vendor/gopkg.in/cheggaaa/pb.v1/pool_win.go
+++ b/vendor/gopkg.in/cheggaaa/pb.v1/pool_win.go
@@ -8,13 +8,18 @@ import (
)
func (p *Pool) print(first bool) bool {
+ p.m.Lock()
+ defer p.m.Unlock()
var out string
if !first {
coords, err := getCursorPos()
if err != nil {
log.Panic(err)
}
- coords.Y -= int16(len(p.bars))
+ coords.Y -= int16(p.lastBarsCount)
+ if coords.Y < 0 {
+ coords.Y = 0
+ }
coords.X = 0
err = setCursorPos(coords)
@@ -24,12 +29,17 @@ func (p *Pool) print(first bool) bool {
}
isFinished := true
for _, bar := range p.bars {
- if !bar.isFinish {
+ if !bar.IsFinished() {
isFinished = false
}
bar.Update()
out += fmt.Sprintf("\r%s\n", bar.String())
}
- fmt.Print(out)
+ if p.Output != nil {
+ fmt.Fprint(p.Output, out)
+ } else {
+ fmt.Print(out)
+ }
+ p.lastBarsCount = len(p.bars)
return isFinished
}
diff --git a/vendor/gopkg.in/cheggaaa/pb.v1/pool_x.go b/vendor/gopkg.in/cheggaaa/pb.v1/pool_x.go
index d95b71d87..a8ae14d2f 100644
--- a/vendor/gopkg.in/cheggaaa/pb.v1/pool_x.go
+++ b/vendor/gopkg.in/cheggaaa/pb.v1/pool_x.go
@@ -5,18 +5,25 @@ package pb
import "fmt"
func (p *Pool) print(first bool) bool {
+ p.m.Lock()
+ defer p.m.Unlock()
var out string
if !first {
- out = fmt.Sprintf("\033[%dA", len(p.bars))
+ out = fmt.Sprintf("\033[%dA", p.lastBarsCount)
}
isFinished := true
for _, bar := range p.bars {
- if !bar.isFinish {
+ if !bar.IsFinished() {
isFinished = false
}
bar.Update()
out += fmt.Sprintf("\r%s\n", bar.String())
}
- fmt.Print(out)
+ if p.Output != nil {
+ fmt.Fprint(p.Output, out)
+ } else {
+ fmt.Print(out)
+ }
+ p.lastBarsCount = len(p.bars)
return isFinished
}
diff --git a/vendor/gopkg.in/cheggaaa/pb.v1/runecount.go b/vendor/gopkg.in/cheggaaa/pb.v1/runecount.go
index d52edd365..c617c55ec 100644
--- a/vendor/gopkg.in/cheggaaa/pb.v1/runecount.go
+++ b/vendor/gopkg.in/cheggaaa/pb.v1/runecount.go
@@ -11,7 +11,7 @@ var ctrlFinder = regexp.MustCompile("\x1b\x5b[0-9]+\x6d")
func escapeAwareRuneCountInString(s string) int {
n := runewidth.StringWidth(s)
for _, sm := range ctrlFinder.FindAllString(s, -1) {
- n -= len(sm)
+ n -= runewidth.StringWidth(sm)
}
return n
}
diff --git a/vendor/gopkg.in/cheggaaa/pb.v1/termios_nix.go b/vendor/gopkg.in/cheggaaa/pb.v1/termios_nix.go
deleted file mode 100644
index ebb3fe87c..000000000
--- a/vendor/gopkg.in/cheggaaa/pb.v1/termios_nix.go
+++ /dev/null
@@ -1,7 +0,0 @@
-// +build linux solaris
-// +build !appengine
-
-package pb
-
-const ioctlReadTermios = 0x5401 // syscall.TCGETS
-const ioctlWriteTermios = 0x5402 // syscall.TCSETS
diff --git a/vendor/gopkg.in/cheggaaa/pb.v1/termios_sysv.go b/vendor/gopkg.in/cheggaaa/pb.v1/termios_sysv.go
new file mode 100644
index 000000000..b10f61859
--- /dev/null
+++ b/vendor/gopkg.in/cheggaaa/pb.v1/termios_sysv.go
@@ -0,0 +1,13 @@
+// Copyright 2013 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build linux solaris
+// +build !appengine
+
+package pb
+
+import "golang.org/x/sys/unix"
+
+const ioctlReadTermios = unix.TCGETS
+const ioctlWriteTermios = unix.TCSETS