Consolidated progress bar's appearance into the GetDefaultProgressBar() function. Updated dependency for cheggaaa's progress-bar from the gopkg.in location to the better maintained one on github.com.
This commit is contained in:
parent
8c6efe336c
commit
ab4490b967
|
@ -20,8 +20,8 @@ import (
|
|||
|
||||
// imports related to each Downloader implementation
|
||||
import (
|
||||
"github.com/cheggaaa/pb"
|
||||
"github.com/jlaffaye/ftp"
|
||||
"gopkg.in/cheggaaa/pb.v1"
|
||||
"io"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
|
@ -83,22 +83,17 @@ func HashForType(t string) hash.Hash {
|
|||
|
||||
// NewDownloadClient returns a new DownloadClient for the given
|
||||
// configuration.
|
||||
func NewDownloadClient(c *DownloadConfig, bar *pb.ProgressBar) *DownloadClient {
|
||||
func NewDownloadClient(c *DownloadConfig, bar pb.ProgressBar) *DownloadClient {
|
||||
const mtu = 1500 /* ethernet */ - 20 /* ipv4 */ - 20 /* tcp */
|
||||
|
||||
// If no custom progress-bar was specified, then create a default one.
|
||||
if bar == nil {
|
||||
bar = pb.New64(0)
|
||||
}
|
||||
|
||||
// Create downloader map if it hasn't been specified already.
|
||||
if c.DownloaderMap == nil {
|
||||
c.DownloaderMap = map[string]Downloader{
|
||||
"file": &FileDownloader{progress: bar, bufferSize: nil},
|
||||
"ftp": &FTPDownloader{progress: bar, userInfo: url.UserPassword("anonymous", "anonymous@"), mtu: mtu},
|
||||
"http": &HTTPDownloader{progress: bar, userAgent: c.UserAgent},
|
||||
"https": &HTTPDownloader{progress: bar, userAgent: c.UserAgent},
|
||||
"smb": &SMBDownloader{progress: bar, bufferSize: nil},
|
||||
"file": &FileDownloader{progress: &bar, bufferSize: nil},
|
||||
"ftp": &FTPDownloader{progress: &bar, userInfo: url.UserPassword("anonymous", "anonymous@"), mtu: mtu},
|
||||
"http": &HTTPDownloader{progress: &bar, userAgent: c.UserAgent},
|
||||
"https": &HTTPDownloader{progress: &bar, userAgent: c.UserAgent},
|
||||
"smb": &SMBDownloader{progress: &bar, bufferSize: nil},
|
||||
}
|
||||
}
|
||||
return &DownloadClient{config: c}
|
||||
|
|
|
@ -7,10 +7,9 @@ import (
|
|||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/cheggaaa/pb"
|
||||
"github.com/hashicorp/packer/packer"
|
||||
"github.com/mitchellh/multistep"
|
||||
|
||||
"gopkg.in/cheggaaa/pb.v1"
|
||||
)
|
||||
|
||||
// StepDownload downloads a remote file using the download client within
|
||||
|
@ -63,6 +62,10 @@ func (s *StepDownload) Run(state multistep.StateBag) multistep.StepAction {
|
|||
|
||||
ui.Say(fmt.Sprintf("Downloading or copying %s", s.Description))
|
||||
|
||||
// Get a default-looking progress bar and connect it to the ui.
|
||||
bar := GetDefaultProgressBar()
|
||||
bar.Callback = ui.Message
|
||||
|
||||
// First try to use any already downloaded file
|
||||
// If it fails, proceed to regualar download logic
|
||||
|
||||
|
@ -96,7 +99,7 @@ func (s *StepDownload) Run(state multistep.StateBag) multistep.StepAction {
|
|||
}
|
||||
downloadConfigs[i] = config
|
||||
|
||||
if match, _ := NewDownloadClient(config, nil).VerifyChecksum(config.TargetPath); match {
|
||||
if match, _ := NewDownloadClient(config, bar).VerifyChecksum(config.TargetPath); match {
|
||||
ui.Message(fmt.Sprintf("Found already downloaded, initial checksum matched, no download needed: %s", url))
|
||||
finalPath = config.TargetPath
|
||||
break
|
||||
|
@ -138,11 +141,7 @@ func (s *StepDownload) Run(state multistep.StateBag) multistep.StepAction {
|
|||
|
||||
func (s *StepDownload) Cleanup(multistep.StateBag) {}
|
||||
|
||||
func (s *StepDownload) download(config *DownloadConfig, state multistep.StateBag) (string, error, bool) {
|
||||
var path string
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
|
||||
// design the appearance of the progress bar
|
||||
func GetDefaultProgressBar() pb.ProgressBar {
|
||||
bar := pb.New64(0)
|
||||
bar.ShowPercent = true
|
||||
bar.ShowCounters = true
|
||||
|
@ -154,9 +153,19 @@ func (s *StepDownload) download(config *DownloadConfig, state multistep.StateBag
|
|||
bar.Format("[=>-]")
|
||||
bar.SetRefreshRate(1 * time.Second)
|
||||
bar.SetWidth(25)
|
||||
|
||||
return *bar
|
||||
}
|
||||
|
||||
func (s *StepDownload) download(config *DownloadConfig, state multistep.StateBag) (string, error, bool) {
|
||||
var path string
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
|
||||
// Get a default looking progress bar and connect it to the ui.
|
||||
bar := GetDefaultProgressBar()
|
||||
bar.Callback = ui.Message
|
||||
|
||||
// create download client with config and progress bar
|
||||
// Create download client with config and progress bar
|
||||
download := NewDownloadClient(config, bar)
|
||||
|
||||
downloadCompleteCh := make(chan error, 1)
|
||||
|
|
7
vendor/gopkg.in/cheggaaa/pb.v1/README.md → vendor/github.com/cheggaaa/pb/README.md
generated
vendored
7
vendor/gopkg.in/cheggaaa/pb.v1/README.md → vendor/github.com/cheggaaa/pb/README.md
generated
vendored
|
@ -1,7 +1,10 @@
|
|||
# Terminal progress bar for Go
|
||||
|
||||
Simple progress bar for console programs.
|
||||
|
||||
[![Join the chat at https://gitter.im/cheggaaa/pb](https://badges.gitter.im/cheggaaa/pb.svg)](https://gitter.im/cheggaaa/pb?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
|
||||
Simple progress bar for console programs.
|
||||
|
||||
Please check the new version https://github.com/cheggaaa/pb/tree/v2 (currently, it's beta)
|
||||
|
||||
## Installation
|
||||
|
|
@ -0,0 +1,118 @@
|
|||
package pb
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
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, 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}
|
||||
}
|
||||
|
||||
type formatter struct {
|
||||
n int64
|
||||
unit Units
|
||||
width int
|
||||
perSec bool
|
||||
}
|
||||
|
||||
func (f *formatter) To(unit Units) *formatter {
|
||||
f.unit = unit
|
||||
return f
|
||||
}
|
||||
|
||||
func (f *formatter) Width(width int) *formatter {
|
||||
f.width = width
|
||||
return f
|
||||
}
|
||||
|
||||
func (f *formatter) PerSec() *formatter {
|
||||
f.perSec = true
|
||||
return f
|
||||
}
|
||||
|
||||
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:
|
||||
out = formatDuration(f.n)
|
||||
default:
|
||||
out = fmt.Sprintf(fmt.Sprintf("%%%dd", f.width), f.n)
|
||||
}
|
||||
if f.perSec {
|
||||
out += "/s"
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Convert bytes to human readable string. Like 2 MiB, 64.2 KiB, 52 B
|
||||
func formatBytes(i int64) (result string) {
|
||||
switch {
|
||||
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)
|
||||
}
|
||||
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)
|
||||
}
|
||||
result = fmt.Sprintf("%s%v", result, d)
|
||||
return
|
||||
}
|
|
@ -13,7 +13,7 @@ import (
|
|||
)
|
||||
|
||||
// Current version
|
||||
const Version = "1.0.6"
|
||||
const Version = "1.0.19"
|
||||
|
||||
const (
|
||||
// Default refresh rate - 200ms
|
||||
|
@ -47,8 +47,6 @@ func New64(total int64) *ProgressBar {
|
|||
Units: U_NO,
|
||||
ManualUpdate: false,
|
||||
finish: make(chan struct{}),
|
||||
currentValue: -1,
|
||||
mu: new(sync.Mutex),
|
||||
}
|
||||
return pb.Format(FORMAT)
|
||||
}
|
||||
|
@ -67,7 +65,8 @@ 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
|
||||
|
@ -91,13 +90,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,7 +112,7 @@ type ProgressBar struct {
|
|||
// Start print
|
||||
func (pb *ProgressBar) Start() *ProgressBar {
|
||||
pb.startTime = time.Now()
|
||||
pb.startValue = pb.current
|
||||
pb.startValue = atomic.LoadInt64(&pb.current)
|
||||
if pb.Total == 0 {
|
||||
pb.ShowTimeLeft = false
|
||||
pb.ShowPercent = false
|
||||
|
@ -173,7 +173,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")
|
||||
|
@ -222,6 +222,8 @@ func (pb *ProgressBar) Finish() {
|
|||
pb.finishOnce.Do(func() {
|
||||
close(pb.finish)
|
||||
pb.write(atomic.LoadInt64(&pb.current))
|
||||
pb.mu.Lock()
|
||||
defer pb.mu.Unlock()
|
||||
switch {
|
||||
case pb.Output != nil:
|
||||
fmt.Fprintln(pb.Output)
|
||||
|
@ -232,6 +234,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()
|
||||
|
@ -290,8 +299,12 @@ func (pb *ProgressBar) write(current int64) {
|
|||
}
|
||||
|
||||
// time left
|
||||
fromStart := time.Now().Sub(pb.startTime)
|
||||
pb.mu.Lock()
|
||||
currentFromStart := current - pb.startValue
|
||||
fromStart := time.Now().Sub(pb.startTime)
|
||||
lastChangeTime := pb.changeTime
|
||||
fromChange := lastChangeTime.Sub(pb.startTime)
|
||||
pb.mu.Unlock()
|
||||
select {
|
||||
case <-pb.finish:
|
||||
if pb.ShowFinalTime {
|
||||
|
@ -301,17 +314,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
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -332,24 +348,32 @@ func (pb *ProgressBar) write(current int64) {
|
|||
size := width - barWidth
|
||||
if size > 0 {
|
||||
if pb.Total > 0 {
|
||||
curCount := int(math.Ceil((float64(current) / float64(pb.Total)) * float64(size)))
|
||||
emptCount := size - curCount
|
||||
curSize := int(math.Ceil((float64(current) / float64(pb.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)
|
||||
}
|
||||
|
@ -364,16 +388,17 @@ 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))
|
||||
if cl := escapeAwareRuneCountInString(out); cl < width {
|
||||
end = strings.Repeat(" ", width-cl)
|
||||
}
|
||||
|
||||
// and print!
|
||||
pb.mu.Lock()
|
||||
pb.lastPrint = out + end
|
||||
isFinish := pb.isFinish
|
||||
pb.mu.Unlock()
|
||||
switch {
|
||||
case pb.isFinish:
|
||||
case isFinish:
|
||||
return
|
||||
case pb.Output != nil:
|
||||
fmt.Fprint(pb.Output, "\r"+out+end)
|
||||
|
@ -406,10 +431,14 @@ 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)
|
||||
if p != c {
|
||||
pb.mu.Lock()
|
||||
pb.changeTime = time.Now()
|
||||
pb.mu.Unlock()
|
||||
atomic.StoreInt64(&pb.previous, c)
|
||||
}
|
||||
pb.write(c)
|
||||
if pb.AutoStat {
|
||||
if c == 0 {
|
||||
pb.startTime = time.Now()
|
||||
|
@ -420,7 +449,10 @@ func (pb *ProgressBar) Update() {
|
|||
}
|
||||
}
|
||||
|
||||
// String return the last bar print
|
||||
func (pb *ProgressBar) String() string {
|
||||
pb.mu.Lock()
|
||||
defer pb.mu.Unlock()
|
||||
return pb.lastPrint
|
||||
}
|
||||
|
||||
|
@ -435,10 +467,3 @@ func (pb *ProgressBar) refresher() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
type window struct {
|
||||
Row uint16
|
||||
Col uint16
|
||||
Xpixel uint16
|
||||
Ypixel uint16
|
||||
}
|
0
vendor/gopkg.in/cheggaaa/pb.v1/pb_win.go → vendor/github.com/cheggaaa/pb/pb_win.go
generated
vendored
0
vendor/gopkg.in/cheggaaa/pb.v1/pb_win.go → vendor/github.com/cheggaaa/pb/pb_win.go
generated
vendored
|
@ -0,0 +1,108 @@
|
|||
// +build linux darwin freebsd netbsd openbsd solaris dragonfly
|
||||
// +build !appengine
|
||||
|
||||
package pb
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/signal"
|
||||
"sync"
|
||||
"syscall"
|
||||
|
||||
"golang.org/x/sys/unix"
|
||||
)
|
||||
|
||||
var ErrPoolWasStarted = errors.New("Bar pool was started")
|
||||
|
||||
var (
|
||||
echoLockMutex sync.Mutex
|
||||
origTermStatePtr *unix.Termios
|
||||
tty *os.File
|
||||
)
|
||||
|
||||
func init() {
|
||||
echoLockMutex.Lock()
|
||||
defer echoLockMutex.Unlock()
|
||||
|
||||
var err error
|
||||
tty, err = os.Open("/dev/tty")
|
||||
if err != nil {
|
||||
tty = os.Stdin
|
||||
}
|
||||
}
|
||||
|
||||
// terminalWidth returns width of the terminal.
|
||||
func terminalWidth() (int, error) {
|
||||
echoLockMutex.Lock()
|
||||
defer echoLockMutex.Unlock()
|
||||
|
||||
fd := int(tty.Fd())
|
||||
|
||||
ws, err := unix.IoctlGetWinsize(fd, unix.TIOCGWINSZ)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return int(ws.Col), nil
|
||||
}
|
||||
|
||||
func lockEcho() (quit chan int, err error) {
|
||||
echoLockMutex.Lock()
|
||||
defer echoLockMutex.Unlock()
|
||||
if origTermStatePtr != nil {
|
||||
return quit, ErrPoolWasStarted
|
||||
}
|
||||
|
||||
fd := int(tty.Fd())
|
||||
|
||||
oldTermStatePtr, err := unix.IoctlGetTermios(fd, ioctlReadTermios)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Can't get terminal settings: %v", err)
|
||||
}
|
||||
|
||||
oldTermios := *oldTermStatePtr
|
||||
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)
|
||||
}
|
||||
|
||||
quit = make(chan int, 1)
|
||||
go catchTerminate(quit)
|
||||
return
|
||||
}
|
||||
|
||||
func unlockEcho() error {
|
||||
echoLockMutex.Lock()
|
||||
defer echoLockMutex.Unlock()
|
||||
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)
|
||||
}
|
||||
|
||||
origTermStatePtr = nil
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// listen exit signals and restore terminal state
|
||||
func catchTerminate(quit chan int) {
|
||||
sig := make(chan os.Signal, 1)
|
||||
signal.Notify(sig, os.Interrupt, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGKILL)
|
||||
defer signal.Stop(sig)
|
||||
select {
|
||||
case <-quit:
|
||||
unlockEcho()
|
||||
case <-sig:
|
||||
unlockEcho()
|
||||
}
|
||||
}
|
14
vendor/gopkg.in/cheggaaa/pb.v1/pool.go → vendor/github.com/cheggaaa/pb/pool.go
generated
vendored
14
vendor/gopkg.in/cheggaaa/pb.v1/pool.go → vendor/github.com/cheggaaa/pb/pool.go
generated
vendored
|
@ -3,6 +3,7 @@
|
|||
package pb
|
||||
|
||||
import (
|
||||
"io"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
@ -19,14 +20,19 @@ func StartPool(pbs ...*ProgressBar) (pool *Pool, err error) {
|
|||
}
|
||||
|
||||
type Pool struct {
|
||||
RefreshRate time.Duration
|
||||
bars []*ProgressBar
|
||||
quit chan int
|
||||
finishOnce sync.Once
|
||||
Output io.Writer
|
||||
RefreshRate time.Duration
|
||||
bars []*ProgressBar
|
||||
lastBarsCount int
|
||||
quit chan int
|
||||
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
|
16
vendor/gopkg.in/cheggaaa/pb.v1/pool_win.go → vendor/github.com/cheggaaa/pb/pool_win.go
generated
vendored
16
vendor/gopkg.in/cheggaaa/pb.v1/pool_win.go → vendor/github.com/cheggaaa/pb/pool_win.go
generated
vendored
|
@ -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
|
||||
}
|
13
vendor/gopkg.in/cheggaaa/pb.v1/pool_x.go → vendor/github.com/cheggaaa/pb/pool_x.go
generated
vendored
13
vendor/gopkg.in/cheggaaa/pb.v1/pool_x.go → vendor/github.com/cheggaaa/pb/pool_x.go
generated
vendored
|
@ -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
|
||||
}
|
0
vendor/gopkg.in/cheggaaa/pb.v1/reader.go → vendor/github.com/cheggaaa/pb/reader.go
generated
vendored
0
vendor/gopkg.in/cheggaaa/pb.v1/reader.go → vendor/github.com/cheggaaa/pb/reader.go
generated
vendored
|
@ -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
|
||||
}
|
|
@ -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
|
|
@ -1,87 +0,0 @@
|
|||
package pb
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
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
|
||||
// U_DURATION units are formatted in a human readable way (3h14m15s)
|
||||
U_DURATION
|
||||
)
|
||||
|
||||
func Format(i int64) *formatter {
|
||||
return &formatter{n: i}
|
||||
}
|
||||
|
||||
type formatter struct {
|
||||
n int64
|
||||
unit Units
|
||||
width int
|
||||
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
|
||||
}
|
||||
|
||||
func (f *formatter) Width(width int) *formatter {
|
||||
f.width = width
|
||||
return f
|
||||
}
|
||||
|
||||
func (f *formatter) PerSec() *formatter {
|
||||
f.perSec = true
|
||||
return f
|
||||
}
|
||||
|
||||
func (f *formatter) String() (out string) {
|
||||
switch f.unit {
|
||||
case U_BYTES:
|
||||
out = formatBytes(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)
|
||||
default:
|
||||
out = fmt.Sprintf(fmt.Sprintf("%%%dd", f.width), f.n)
|
||||
}
|
||||
if f.perSec {
|
||||
out += "/s"
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Convert bytes to human readable string. Like a 2 MB, 64.2 KB, 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)
|
||||
default:
|
||||
result = fmt.Sprintf("%d B", i)
|
||||
}
|
||||
result = strings.Trim(result, " ")
|
||||
return
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
// +build linux darwin freebsd netbsd openbsd dragonfly
|
||||
// +build !appengine
|
||||
|
||||
package pb
|
||||
|
||||
import "syscall"
|
||||
|
||||
const sysIoctl = syscall.SYS_IOCTL
|
|
@ -1,6 +0,0 @@
|
|||
// +build solaris
|
||||
// +build !appengine
|
||||
|
||||
package pb
|
||||
|
||||
const sysIoctl = 54
|
|
@ -1,110 +0,0 @@
|
|||
// +build linux darwin freebsd netbsd openbsd solaris dragonfly
|
||||
// +build !appengine
|
||||
|
||||
package pb
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/signal"
|
||||
"runtime"
|
||||
"sync"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
TIOCGWINSZ = 0x5413
|
||||
TIOCGWINSZ_OSX = 1074295912
|
||||
)
|
||||
|
||||
var tty *os.File
|
||||
|
||||
var ErrPoolWasStarted = errors.New("Bar pool was started")
|
||||
|
||||
var echoLocked bool
|
||||
var echoLockMutex sync.Mutex
|
||||
|
||||
func init() {
|
||||
var err error
|
||||
tty, err = os.Open("/dev/tty")
|
||||
if err != nil {
|
||||
tty = os.Stdin
|
||||
}
|
||||
}
|
||||
|
||||
// terminalWidth returns width of the terminal.
|
||||
func terminalWidth() (int, error) {
|
||||
w := new(window)
|
||||
tio := syscall.TIOCGWINSZ
|
||||
if runtime.GOOS == "darwin" {
|
||||
tio = TIOCGWINSZ_OSX
|
||||
}
|
||||
res, _, err := syscall.Syscall(sysIoctl,
|
||||
tty.Fd(),
|
||||
uintptr(tio),
|
||||
uintptr(unsafe.Pointer(w)),
|
||||
)
|
||||
if int(res) == -1 {
|
||||
return 0, err
|
||||
}
|
||||
return int(w.Col), nil
|
||||
}
|
||||
|
||||
var oldState syscall.Termios
|
||||
|
||||
func lockEcho() (quit chan int, err error) {
|
||||
echoLockMutex.Lock()
|
||||
defer echoLockMutex.Unlock()
|
||||
if echoLocked {
|
||||
err = ErrPoolWasStarted
|
||||
return
|
||||
}
|
||||
echoLocked = true
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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)
|
||||
return
|
||||
}
|
||||
|
||||
func unlockEcho() (err 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")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// listen exit signals and restore terminal state
|
||||
func catchTerminate(quit chan int) {
|
||||
sig := make(chan os.Signal, 1)
|
||||
signal.Notify(sig, os.Interrupt, syscall.SIGQUIT, syscall.SIGTERM, syscall.SIGKILL)
|
||||
defer signal.Stop(sig)
|
||||
select {
|
||||
case <-quit:
|
||||
unlockEcho()
|
||||
case <-sig:
|
||||
unlockEcho()
|
||||
}
|
||||
}
|
|
@ -1,7 +0,0 @@
|
|||
// +build linux solaris
|
||||
// +build !appengine
|
||||
|
||||
package pb
|
||||
|
||||
const ioctlReadTermios = 0x5401 // syscall.TCGETS
|
||||
const ioctlWriteTermios = 0x5402 // syscall.TCSETS
|
|
@ -565,6 +565,12 @@
|
|||
"path": "github.com/biogo/hts/bgzf",
|
||||
"revision": "50da7d4131a3b5c9d063932461cab4d1fafb20b0"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "ymc5+iJ+1ipls3ihqPdzMjFYCqo=",
|
||||
"path": "github.com/cheggaaa/pb",
|
||||
"revision": "18d384da9bdc1e5a08fc2a62a494c321d9ae74ea",
|
||||
"revisionTime": "2017-12-14T13:20:59Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "Lf3uUXTkKK5DJ37BxQvxO1Fq+K8=",
|
||||
"comment": "v1.0.0-3-g6d21280",
|
||||
|
@ -1493,12 +1499,6 @@
|
|||
"path": "google.golang.org/cloud/internal",
|
||||
"revision": "5a3b06f8b5da3b7c3a93da43163b872c86c509ef"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "w3z2xM4+RT/OWvVusDgNXZZEEkE=",
|
||||
"path": "gopkg.in/cheggaaa/pb.v1",
|
||||
"revision": "d7e6ca3010b6f084d8056847f55d7f572f180678",
|
||||
"revisionTime": "2016-11-21T09:29:06Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "gY2M/3SCxqgrPz+P/N6JQ+m/wnA=",
|
||||
"path": "gopkg.in/xmlpath.v2",
|
||||
|
|
Loading…
Reference in New Issue