Godeps: semantic versioning cheggaaa/pb

Fix https://github.com/coreos/etcd/issues/4832.
This commit is contained in:
Gyu-Ho Lee 2016-03-21 22:06:16 -07:00
parent e73ac5bdd7
commit bb9a7f5a7c
43 changed files with 681 additions and 763 deletions

13
Godeps/Godeps.json generated
View File

@ -27,10 +27,6 @@
"Comment": "v1.1.0-81-g0fd4c05",
"Rev": "0fd4c0547d204c7b1cad6db6f3adad5f2cf453e5"
},
{
"ImportPath": "github.com/cheggaaa/pb",
"Rev": "da1f27ad1d9509b16f65f52fd9d8138b0f2dc7b2"
},
{
"ImportPath": "github.com/cockroachdb/cmux",
"Rev": "112f0506e7743d64a6eb8fedbcff13d9979bbf92"
@ -119,10 +115,6 @@
"ImportPath": "github.com/olekukonko/tablewriter",
"Rev": "cca8bbc0798408af109aaaa239cbd2634846b340"
},
{
"ImportPath": "github.com/olekukonko/ts",
"Rev": "ecf753e7c962639ab5a1fb46f7da627d4c0a04b8"
},
{
"ImportPath": "github.com/prometheus/client_golang/prometheus",
"Comment": "0.7.0-52-ge51041b",
@ -209,6 +201,11 @@
{
"ImportPath": "google.golang.org/grpc",
"Rev": "b88c12e7caf74af3928de99a864aaa9916fa5aad"
},
{
"ImportPath": "gopkg.in/cheggaaa/pb.v1",
"Comment": "v1.0.1",
"Rev": "29ad9b62f9e0274422d738242b94a5b89440bfa6"
}
]
}

View File

@ -1,98 +0,0 @@
## Terminal progress bar for Go
Simple progress bar for console programms.
### Installation
```
go get github.com/cheggaaa/pb
```
### Usage
```Go
package main
import (
"github.com/cheggaaa/pb"
"time"
)
func main() {
count := 100000
bar := pb.StartNew(count)
for i := 0; i < count; i++ {
bar.Increment()
time.Sleep(time.Millisecond)
}
bar.FinishPrint("The End!")
}
```
Result will be like this:
```
> go run test.go
37158 / 100000 [================>_______________________________] 37.16% 1m11s
```
More functions?
```Go
// create bar
bar := pb.New(count)
// refresh info every second (default 200ms)
bar.SetRefreshRate(time.Second)
// show percents (by default already true)
bar.ShowPercent = true
// show bar (by default already true)
bar.ShowBar = true
// no need counters
bar.ShowCounters = false
// show "time left"
bar.ShowTimeLeft = true
// show average speed
bar.ShowSpeed = true
// sets the width of the progress bar
bar.SetWidth(80)
// sets the width of the progress bar, but if terminal size smaller will be ignored
bar.SetMaxWidth(80)
// convert output to readable format (like KB, MB)
bar.SetUnits(pb.U_BYTES)
// and start
bar.Start()
```
Want handle progress of io operations?
```Go
// create and start bar
bar := pb.New(myDataLen).SetUnits(pb.U_BYTES)
bar.Start()
// my io.Reader
r := myReader
// my io.Writer
w := myWriter
// create multi writer
writer := io.MultiWriter(w, bar)
// and copy
io.Copy(writer, r)
// show example/copy/copy.go for advanced example
```
Not like the looks?
```Go
bar.Format("<.- >")
```

View File

@ -1,81 +0,0 @@
package main
import (
"fmt"
"github.com/coreos/etcd/Godeps/_workspace/src/github.com/cheggaaa/pb"
"io"
"net/http"
"os"
"strconv"
"strings"
"time"
)
func main() {
// check args
if len(os.Args) < 3 {
printUsage()
return
}
sourceName, destName := os.Args[1], os.Args[2]
// check source
var source io.Reader
var sourceSize int64
if strings.HasPrefix(sourceName, "http://") {
// open as url
resp, err := http.Get(sourceName)
if err != nil {
fmt.Printf("Can't get %s: %v\n", sourceName, err)
return
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
fmt.Printf("Server return non-200 status: %v\n", resp.Status)
return
}
i, _ := strconv.Atoi(resp.Header.Get("Content-Length"))
sourceSize = int64(i)
source = resp.Body
} else {
// open as file
s, err := os.Open(sourceName)
if err != nil {
fmt.Printf("Can't open %s: %v\n", sourceName, err)
return
}
defer s.Close()
// get source size
sourceStat, err := s.Stat()
if err != nil {
fmt.Printf("Can't stat %s: %v\n", sourceName, err)
return
}
sourceSize = sourceStat.Size()
source = s
}
// create dest
dest, err := os.Create(destName)
if err != nil {
fmt.Printf("Can't create %s: %v\n", destName, err)
return
}
defer dest.Close()
// create bar
bar := pb.New(int(sourceSize)).SetUnits(pb.U_BYTES).SetRefreshRate(time.Millisecond * 10)
bar.ShowSpeed = true
bar.Start()
// create multi writer
writer := io.MultiWriter(dest, bar)
// and copy
io.Copy(writer, source)
bar.Finish()
}
func printUsage() {
fmt.Println("copy [source file or url] [dest file]")
}

View File

@ -1,30 +0,0 @@
package main
import (
"github.com/coreos/etcd/Godeps/_workspace/src/github.com/cheggaaa/pb"
"time"
)
func main() {
count := 5000
bar := pb.New(count)
// show percents (by default already true)
bar.ShowPercent = true
// show bar (by default already true)
bar.ShowBar = true
// no need counters
bar.ShowCounters = true
bar.ShowTimeLeft = true
// and start
bar.Start()
for i := 0; i < count; i++ {
bar.Increment()
time.Sleep(time.Millisecond)
}
bar.FinishPrint("The End!")
}

View File

@ -1,45 +0,0 @@
package pb
import (
"fmt"
"strconv"
"strings"
)
type Units int
const (
// By default, without type handle
U_NO Units = iota
// Handle as b, Kb, Mb, etc
U_BYTES
)
// Format integer
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)
}
}
// 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
}

View File

@ -1,37 +0,0 @@
package pb
import (
"fmt"
"strconv"
"testing"
)
func Test_DefaultsToInteger(t *testing.T) {
value := int64(1000)
expected := strconv.Itoa(int(value))
actual := Format(value, -1)
if actual != expected {
t.Error(fmt.Sprintf("Expected {%s} was {%s}", expected, actual))
}
}
func Test_CanFormatAsInteger(t *testing.T) {
value := int64(1000)
expected := strconv.Itoa(int(value))
actual := Format(value, U_NO)
if actual != expected {
t.Error(fmt.Sprintf("Expected {%s} was {%s}", expected, actual))
}
}
func Test_CanFormatAsBytes(t *testing.T) {
value := int64(1000)
expected := "1000 B"
actual := Format(value, U_BYTES)
if actual != expected {
t.Error(fmt.Sprintf("Expected {%s} was {%s}", expected, actual))
}
}

View File

@ -1,7 +0,0 @@
// +build linux darwin freebsd netbsd openbsd
package pb
import "syscall"
const sys_ioctl = syscall.SYS_IOCTL

View File

@ -1,5 +0,0 @@
// +build solaris
package pb
const sys_ioctl = 54

View File

@ -1,37 +0,0 @@
package pb
import (
"testing"
)
func Test_IncrementAddsOne(t *testing.T) {
count := 5000
bar := New(count)
expected := 1
actual := bar.Increment()
if actual != expected {
t.Errorf("Expected {%d} was {%d}", expected, actual)
}
}
func Test_Width(t *testing.T) {
count := 5000
bar := New(count)
width := 100
bar.SetWidth(100).Callback = func(out string) {
if len(out) != width {
t.Errorf("Bar width expected {%d} was {%d}", len(out), width)
}
}
bar.Start()
bar.Increment()
bar.Finish()
}
func Test_MultipleFinish(t *testing.T) {
bar := New(5000)
bar.Add(2000)
bar.Finish()
bar.Finish()
}

View File

@ -1,16 +0,0 @@
// +build windows
package pb
import (
"github.com/coreos/etcd/Godeps/_workspace/src/github.com/olekukonko/ts"
)
func bold(str string) string {
return str
}
func terminalWidth() (int, error) {
size, err := ts.GetSize()
return size.Col(), err
}

View File

@ -1,46 +0,0 @@
// +build linux darwin freebsd netbsd openbsd solaris
package pb
import (
"os"
"runtime"
"syscall"
"unsafe"
)
const (
TIOCGWINSZ = 0x5413
TIOCGWINSZ_OSX = 1074295912
)
var tty *os.File
func init() {
var err error
tty, err = os.Open("/dev/tty")
if err != nil {
tty = os.Stdin
}
}
func bold(str string) string {
return "\033[1m" + str + "\033[0m"
}
func terminalWidth() (int, error) {
w := new(window)
tio := syscall.TIOCGWINSZ
if runtime.GOOS == "darwin" {
tio = TIOCGWINSZ_OSX
}
res, _, err := syscall.Syscall(sys_ioctl,
tty.Fd(),
uintptr(tio),
uintptr(unsafe.Pointer(w)),
)
if int(res) == -1 {
return 0, err
}
return int(w.Col), nil
}

View File

@ -1,6 +0,0 @@
language: go
go:
- 1.1
- 1.2
- tip

View File

@ -1,19 +0,0 @@
Copyright (C) 2014 by Oleku Konko
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@ -1,28 +0,0 @@
ts (Terminal Size)
==
[![Build Status](https://travis-ci.org/olekukonko/ts.png?branch=master)](https://travis-ci.org/olekukonko/ts) [![Total views](https://sourcegraph.com/api/repos/github.com/olekukonko/ts/counters/views.png)](https://sourcegraph.com/github.com/olekukonko/ts)
Simple go Application to get Terminal Size. So Many Implementations do not support windows but `ts` has full windows support.
Run `go get github.com/olekukonko/ts` to download and install
#### Example
```go
package main
import (
"fmt"
"github.com/olekukonko/ts"
)
func main() {
size, _ := ts.GetSize()
fmt.Println(size.Col()) // Get Width
fmt.Println(size.Row()) // Get Height
fmt.Println(size.PosX()) // Get X position
fmt.Println(size.PosY()) // Get Y position
}
```
[See Documentation](http://godoc.org/github.com/olekukonko/ts)

View File

@ -1,36 +0,0 @@
// Copyright 2014 Oleku Konko All rights reserved.
// Use of this source code is governed by a MIT
// license that can be found in the LICENSE file.
// This module is a Terminal API for the Go Programming Language.
// The protocols were written in pure Go and works on windows and unix systems
/**
Simple go Application to get Terminal Size. So Many Implementations do not support windows but `ts` has full windows support.
Run `go get github.com/olekukonko/ts` to download and install
Installation
Minimum requirements are Go 1.1+ with fill Windows support
Example
package main
import (
"fmt"
"github.com/olekukonko/ts"
)
func main() {
size, _ := ts.GetSize()
fmt.Println(size.Col()) // Get Width
fmt.Println(size.Row()) // Get Height
fmt.Println(size.PosX()) // Get X position
fmt.Println(size.PosY()) // Get Y position
}
**/
package ts

View File

@ -1,36 +0,0 @@
// Copyright 2014 Oleku Konko All rights reserved.
// Use of this source code is governed by a MIT
// license that can be found in the LICENSE file.
// This module is a Terminal API for the Go Programming Language.
// The protocols were written in pure Go and works on windows and unix systems
package ts
// Return System Size
type Size struct {
row uint16
col uint16
posX uint16
posY uint16
}
// Get Terminal Width
func (w Size) Col() int {
return int(w.col)
}
// Get Terminal Height
func (w Size) Row() int {
return int(w.row)
}
// Get Position X
func (w Size) PosX() int {
return int(w.posX)
}
// Get Position Y
func (w Size) PosY() int {
return int(w.posY)
}

View File

@ -1,14 +0,0 @@
// +build darwin
// Copyright 2014 Oleku Konko All rights reserved.
// Use of this source code is governed by a MIT
// license that can be found in the LICENSE file.
// This module is a Terminal API for the Go Programming Language.
// The protocols were written in pure Go and works on windows and unix systems
package ts
const (
TIOCGWINSZ = 0x40087468
)

View File

@ -1,13 +0,0 @@
// +build linux
// Copyright 2014 Oleku Konko All rights reserved.
// Use of this source code is governed by a MIT
// license that can be found in the LICENSE file.
// This module is a Terminal API for the Go Programming Language.
// The protocols were written in pure Go and works on windows and unix systems
package ts
const (
TIOCGWINSZ = 0x5413
)

View File

@ -1,14 +0,0 @@
// +build !windows,!darwin,!freebsd,!netbsd,!openbsd,!linux
// Copyright 2014 Oleku Konko All rights reserved.
// Use of this source code is governed by a MIT
// license that can be found in the LICENSE file.
// This module is a Terminal API for the Go Programming Language.
// The protocols were written in pure Go and works on windows and unix systems
package ts
const (
TIOCGWINSZ = 0
)

View File

@ -1,32 +0,0 @@
// Copyright 2014 Oleku Konko All rights reserved.
// Use of this source code is governed by a MIT
// license that can be found in the LICENSE file.
// This module is a Terminal API for the Go Programming Language.
// The protocols were written in pure Go and works on windows and unix systems
package ts
import (
"fmt"
"testing"
)
func ExampleGetSize() {
size, _ := GetSize()
fmt.Println(size.Col()) // Get Width
fmt.Println(size.Row()) // Get Height
fmt.Println(size.PosX()) // Get X position
fmt.Println(size.PosY()) // Get Y position
}
func TestSize(t *testing.T) {
size, err := GetSize()
if err != nil {
t.Fatal(err)
}
if size.Col() == 0 || size.Row() == 0 {
t.Fatalf("Screen Size Failed")
}
}

View File

@ -1,14 +0,0 @@
// +build freebsd netbsd openbsd
// Copyright 2014 Oleku Konko All rights reserved.
// Use of this source code is governed by a MIT
// license that can be found in the LICENSE file.
// This module is a Terminal API for the Go Programming Language.
// The protocols were written in pure Go and works on windows and unix systems
package ts
const (
TIOCGWINSZ = 0x40087468
)

View File

@ -1,64 +0,0 @@
// +build windows
// Copyright 2014 Oleku Konko All rights reserved.
// Use of this source code is governed by a MIT
// license that can be found in the LICENSE file.
// This module is a Terminal API for the Go Programming Language.
// The protocols were written in pure Go and works on windows and unix systems
package ts
import (
"syscall"
"unsafe"
)
var (
kernel32 = syscall.NewLazyDLL("kernel32.dll")
// Retrieves information about the specified console screen buffer.
// See http://msdn.microsoft.com/en-us/library/windows/desktop/ms683171(v=vs.85).aspx
screenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo")
)
// Contains information about a console screen buffer.
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms682093(v=vs.85).aspx
type CONSOLE_SCREEN_BUFFER_INFO struct {
DwSize COORD
DwCursorPosition COORD
WAttributes uint16
SrWindow SMALL_RECT
DwMaximumWindowSize COORD
}
// Defines the coordinates of a character cell in a console screen buffer.
// The origin of the coordinate system (0,0) is at the top, left cell of the buffer.
// See http://msdn.microsoft.com/en-us/library/windows/desktop/ms682119(v=vs.85).aspx
type COORD struct {
X, Y uint16
}
// Defines the coordinates of the upper left and lower right corners of a rectangle.
// See http://msdn.microsoft.com/en-us/library/windows/desktop/ms686311(v=vs.85).aspx
type SMALL_RECT struct {
Left, Top, Right, Bottom uint16
}
func GetSize() (ws Size, err error) {
var info CONSOLE_SCREEN_BUFFER_INFO
rc, _, err := screenBufferInfo.Call(
uintptr(syscall.Stdout),
uintptr(unsafe.Pointer(&info)))
if rc == 0 {
return ws, err
}
ws = Size{info.SrWindow.Bottom,
info.SrWindow.Right,
info.DwCursorPosition.X,
info.DwCursorPosition.Y}
return ws, nil
}

View File

@ -1,46 +0,0 @@
// +build !windows
// Copyright 2014 Oleku Konko All rights reserved.
// Use of this source code is governed by a MIT
// license that can be found in the LICENSE file.
// This module is a Terminal API for the Go Programming Language.
// The protocols were written in pure Go and works on windows and unix systems
package ts
import (
"syscall"
"unsafe"
)
// Get Windows Size
func GetSize() (ws Size, err error) {
_, _, ec := syscall.Syscall(syscall.SYS_IOCTL,
uintptr(syscall.Stdout),
uintptr(TIOCGWINSZ),
uintptr(unsafe.Pointer(&ws)))
err = getError(ec)
if TIOCGWINSZ == 0 && err != nil {
ws = Size{80, 25, 0, 0}
}
return ws, err
}
func getError(ec interface{}) (err error) {
switch v := ec.(type) {
case syscall.Errno: // Some implementation return syscall.Errno number
if v != 0 {
err = syscall.Errno(v)
}
case error: // Some implementation return error
err = ec.(error)
default:
err = nil
}
return
}

View File

@ -2,3 +2,6 @@ language: go
go:
- 1.4.2
sudo: false
os:
- linux
- osx

View File

@ -1,4 +1,4 @@
Copyright (c) 2012, Sergey Cherepanov
Copyright (c) 2012-2015, Sergey Cherepanov
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

176
Godeps/_workspace/src/gopkg.in/cheggaaa/pb.v1/README.md generated vendored Normal file
View File

@ -0,0 +1,176 @@
# Terminal progress bar for Go
Simple progress bar for console programs.
## Installation
```
go get gopkg.in/cheggaaa/pb.v1
```
## Usage
```Go
package main
import (
"gopkg.in/cheggaaa/pb.v1"
"time"
)
func main() {
count := 100000
bar := pb.StartNew(count)
for i := 0; i < count; i++ {
bar.Increment()
time.Sleep(time.Millisecond)
}
bar.FinishPrint("The End!")
}
```
Result will be like this:
```
> go run test.go
37158 / 100000 [================>_______________________________] 37.16% 1m11s
```
## Customization
```Go
// create bar
bar := pb.New(count)
// refresh info every second (default 200ms)
bar.SetRefreshRate(time.Second)
// show percents (by default already true)
bar.ShowPercent = true
// show bar (by default already true)
bar.ShowBar = true
// no counters
bar.ShowCounters = false
// show "time left"
bar.ShowTimeLeft = true
// show average speed
bar.ShowSpeed = true
// sets the width of the progress bar
bar.SetWidth(80)
// sets the width of the progress bar, but if terminal size smaller will be ignored
bar.SetMaxWidth(80)
// convert output to readable format (like KB, MB)
bar.SetUnits(pb.U_BYTES)
// and start
bar.Start()
```
## Progress bar for IO Operations
```go
// create and start bar
bar := pb.New(myDataLen).SetUnits(pb.U_BYTES)
bar.Start()
// my io.Reader
r := myReader
// my io.Writer
w := myWriter
// create proxy reader
reader := bar.NewProxyReader(r)
// and copy from pb reader
io.Copy(w, reader)
```
```go
// create and start bar
bar := pb.New(myDataLen).SetUnits(pb.U_BYTES)
bar.Start()
// my io.Reader
r := myReader
// my io.Writer
w := myWriter
// create multi writer
writer := io.MultiWriter(w, bar)
// and copy
io.Copy(writer, r)
```
## Custom Progress Bar Look-and-feel
```go
bar.Format("<.- >")
```
## Multiple Progress Bars (experimental and unstable)
#####Multiple bars do not works at Windows!!!
Do not print to terminal while pool is active.
```go
package main
import (
"math/rand"
"sync"
"time"
"gopkg.in/cheggaaa/pb.v1"
)
func main() {
// create bars
first := pb.New(200).Prefix("First ")
second := pb.New(200).Prefix("Second ")
third := pb.New(200).Prefix("Third ")
// start pool
pool, err := pb.StartPool(first, second, third)
if err != nil {
panic(err)
}
// update bars
wg := new(sync.WaitGroup)
for _, bar := range []*pb.ProgressBar{first, second, third} {
wg.Add(1)
go func(cb *pb.ProgressBar) {
for n := 0; n < 200; n++ {
cb.Increment()
time.Sleep(time.Millisecond * time.Duration(rand.Intn(100)))
}
cb.Finish()
wg.Done()
}(bar)
}
wg.Wait()
// close pool
pool.Stop()
}
```
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
```

View File

@ -0,0 +1,87 @@
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
}

View File

@ -1,3 +1,4 @@
// Simple console progress bars
package pb
import (
@ -11,6 +12,9 @@ import (
"unicode/utf8"
)
// Current version
const Version = "1.0.1"
const (
// Default refresh rate - 200ms
DEFAULT_REFRESH_RATE = time.Millisecond * 200
@ -30,7 +34,7 @@ func New(total int) *ProgressBar {
return New64(int64(total))
}
// Create new progress bar object uding int64 as total
// Create new progress bar object using int64 as total
func New64(total int64) *ProgressBar {
pb := &ProgressBar{
Total: total,
@ -42,8 +46,9 @@ func New64(total int64) *ProgressBar {
ShowFinalTime: true,
Units: U_NO,
ManualUpdate: false,
isFinish: make(chan struct{}),
finish: make(chan struct{}),
currentValue: -1,
mu: new(sync.Mutex),
}
return pb.Format(FORMAT)
}
@ -77,8 +82,13 @@ type ProgressBar struct {
ForceWidth bool
ManualUpdate bool
// Default width for the time box.
UnitsWidth int
TimeBoxWidth int
finishOnce sync.Once //Guards isFinish
isFinish chan struct{}
finish chan struct{}
isFinish bool
startTime time.Time
startValue int64
@ -86,11 +96,16 @@ type ProgressBar struct {
prefix, postfix string
mu *sync.Mutex
lastPrint string
BarStart string
BarEnd string
Empty string
Current string
CurrentN string
AlwaysUpdate bool
}
// Start print
@ -102,7 +117,8 @@ func (pb *ProgressBar) Start() *ProgressBar {
pb.ShowPercent = false
}
if !pb.ManualUpdate {
go pb.writer()
pb.Update() // Initial printing of the bar before running the bar refresher.
go pb.refresher()
}
return pb
}
@ -146,8 +162,14 @@ func (pb *ProgressBar) Postfix(postfix string) *ProgressBar {
// Set custom format for bar
// Example: bar.Format("[=>_]")
// Example: bar.Format("[\x00=\x00>\x00-\x00]") // \x00 is the delimiter
func (pb *ProgressBar) Format(format string) *ProgressBar {
formatEntries := strings.Split(format, "")
var formatEntries []string
if len(format) == 5 {
formatEntries = strings.Split(format, "")
} else {
formatEntries = strings.Split(format, "\x00")
}
if len(formatEntries) == 5 {
pb.BarStart = formatEntries[0]
pb.BarEnd = formatEntries[4]
@ -190,11 +212,12 @@ func (pb *ProgressBar) SetWidth(width int) *ProgressBar {
func (pb *ProgressBar) Finish() {
//Protect multiple calls
pb.finishOnce.Do(func() {
close(pb.isFinish)
close(pb.finish)
pb.write(atomic.LoadInt64(&pb.current))
if !pb.NotPrint {
fmt.Println()
}
pb.isFinish = true
})
}
@ -230,16 +253,23 @@ func (pb *ProgressBar) write(current int64) {
// percents
if pb.ShowPercent {
percent := float64(current) / (float64(pb.Total) / float64(100))
percentBox = fmt.Sprintf(" %.02f %% ", percent)
var percent float64
if pb.Total > 0 {
percent = float64(current) / (float64(pb.Total) / float64(100))
} else {
percent = float64(current) / float64(100)
}
percentBox = fmt.Sprintf(" %6.02f%%", percent)
}
// counters
if pb.ShowCounters {
current := Format(current).To(pb.Units).Width(pb.UnitsWidth)
if pb.Total > 0 {
countersBox = fmt.Sprintf("%s / %s ", Format(current, pb.Units), Format(pb.Total, pb.Units))
total := Format(pb.Total).To(pb.Units).Width(pb.UnitsWidth)
countersBox = fmt.Sprintf(" %s / %s ", current, total)
} else {
countersBox = Format(current, pb.Units) + " / ? "
countersBox = fmt.Sprintf(" %s / ? ", current)
}
}
@ -247,28 +277,44 @@ func (pb *ProgressBar) write(current int64) {
fromStart := time.Now().Sub(pb.startTime)
currentFromStart := current - pb.startValue
select {
case <-pb.isFinish:
case <-pb.finish:
if pb.ShowFinalTime {
left := (fromStart / time.Second) * time.Second
var left time.Duration
if pb.Total > 0 {
left = (fromStart / time.Second) * time.Second
} else {
left = (time.Duration(currentFromStart) / 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()
var left time.Duration
if pb.Total > 0 {
left = time.Duration(pb.Total-currentFromStart) * perEntry
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 len(timeLeftBox) < pb.TimeBoxWidth {
timeLeftBox = fmt.Sprintf("%s%s", strings.Repeat(" ", pb.TimeBoxWidth-len(timeLeftBox)), timeLeftBox)
}
// speed
if pb.ShowSpeed && currentFromStart > 0 {
fromStart := time.Now().Sub(pb.startTime)
speed := float64(currentFromStart) / (float64(fromStart) / float64(time.Second))
speedBox = Format(int64(speed), pb.Units) + "/s "
speedBox = " " + Format(int64(speed)).To(pb.Units).Width(pb.UnitsWidth).PerSec().String()
}
barWidth := utf8.RuneCountInString(countersBox + pb.BarStart + pb.BarEnd + percentBox + timeLeftBox + speedBox + pb.prefix + pb.postfix)
barWidth := escapeAwareRuneCountInString(countersBox + pb.BarStart + pb.BarEnd + percentBox + timeLeftBox + speedBox + pb.prefix + pb.postfix)
// bar
if pb.ShowBar {
size := width - barWidth
@ -288,10 +334,8 @@ func (pb *ProgressBar) write(current int64) {
} else if curCount > 0 {
barBox += strings.Repeat(pb.Current, curCount-1) + pb.CurrentN
}
barBox += strings.Repeat(pb.Empty, emptCount) + pb.BarEnd
} else {
barBox = pb.BarStart
pos := size - int(current)%int(size)
if pos-1 > 0 {
@ -308,12 +352,17 @@ func (pb *ProgressBar) write(current int64) {
// check len
out = pb.prefix + countersBox + barBox + percentBox + speedBox + timeLeftBox + pb.postfix
if utf8.RuneCountInString(out) < width {
if escapeAwareRuneCountInString(out) < width {
end = strings.Repeat(" ", width-utf8.RuneCountInString(out))
}
// and print!
pb.mu.Lock()
pb.lastPrint = out + end
pb.mu.Unlock()
switch {
case pb.isFinish:
return
case pb.Output != nil:
fmt.Fprint(pb.Output, "\r"+out+end)
case pb.Callback != nil:
@ -323,6 +372,11 @@ func (pb *ProgressBar) write(current int64) {
}
}
// GetTerminalWidth - returns terminal width for all platforms.
func GetTerminalWidth() (int, error) {
return terminalWidth()
}
func (pb *ProgressBar) GetWidth() int {
if pb.ForceWidth {
return pb.Width
@ -340,18 +394,21 @@ func (pb *ProgressBar) GetWidth() int {
// Write the current state of the progressbar
func (pb *ProgressBar) Update() {
c := atomic.LoadInt64(&pb.current)
if c != pb.currentValue {
if pb.AlwaysUpdate || c != pb.currentValue {
pb.write(c)
pb.currentValue = c
}
}
// Internal loop for writing progressbar
func (pb *ProgressBar) writer() {
pb.Update()
func (pb *ProgressBar) String() string {
return pb.lastPrint
}
// Internal loop for refreshing the progressbar
func (pb *ProgressBar) refresher() {
for {
select {
case <-pb.isFinish:
case <-pb.finish:
return
case <-time.After(pb.RefreshRate):
pb.Update()

View File

@ -0,0 +1,11 @@
// +build appengine
package pb
import "errors"
// terminalWidth returns width of the terminal, which is not supported
// and should always failed on appengine classic which is a sandboxed PaaS.
func terminalWidth() (int, error) {
return 0, errors.New("Not supported")
}

View File

@ -0,0 +1,8 @@
// +build linux darwin freebsd netbsd openbsd dragonfly
// +build !appengine
package pb
import "syscall"
const sysIoctl = syscall.SYS_IOCTL

View File

@ -0,0 +1,6 @@
// +build solaris
// +build !appengine
package pb
const sysIoctl = 54

View File

@ -0,0 +1,61 @@
// +build windows
package pb
import (
"os"
"syscall"
"unsafe"
)
var tty = os.Stdin
var (
kernel32 = syscall.NewLazyDLL("kernel32.dll")
// GetConsoleScreenBufferInfo retrieves information about the
// specified console screen buffer.
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms683171(v=vs.85).aspx
procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo")
)
type (
// Defines the coordinates of the upper left and lower right corners
// of a rectangle.
// See
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms686311(v=vs.85).aspx
smallRect struct {
Left, Top, Right, Bottom int16
}
// Defines the coordinates of a character cell in a console screen
// buffer. The origin of the coordinate system (0,0) is at the top, left cell
// of the buffer.
// See
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms682119(v=vs.85).aspx
coordinates struct {
X, Y int16
}
word int16
// Contains information about a console screen buffer.
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms682093(v=vs.85).aspx
consoleScreenBufferInfo struct {
dwSize coordinates
dwCursorPosition coordinates
wAttributes word
srWindow smallRect
dwMaximumWindowSize coordinates
}
)
// terminalWidth returns width of the terminal.
func terminalWidth() (width int, err error) {
var info consoleScreenBufferInfo
_, _, e := syscall.Syscall(procGetConsoleScreenBufferInfo.Addr(), 2, uintptr(syscall.Stdout), uintptr(unsafe.Pointer(&info)), 0)
if e != 0 {
return 0, error(e)
}
return int(info.dwSize.X), nil
}

110
Godeps/_workspace/src/gopkg.in/cheggaaa/pb.v1/pb_x.go generated vendored Normal file
View File

@ -0,0 +1,110 @@
// +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()
}
}

93
Godeps/_workspace/src/gopkg.in/cheggaaa/pb.v1/pool.go generated vendored Normal file
View File

@ -0,0 +1,93 @@
// +build linux darwin freebsd netbsd openbsd solaris dragonfly
package pb
import (
"fmt"
"sync"
"time"
)
// Create and start new pool with given bars
// You need call pool.Stop() after work
func StartPool(pbs ...*ProgressBar) (pool *Pool, err error) {
pool = new(Pool)
if err = pool.start(); err != nil {
return
}
pool.add(pbs...)
return
}
type Pool struct {
RefreshRate time.Duration
bars []*ProgressBar
quit chan int
finishOnce sync.Once
}
func (p *Pool) add(pbs ...*ProgressBar) {
for _, bar := range pbs {
bar.ManualUpdate = true
bar.NotPrint = true
bar.Start()
p.bars = append(p.bars, bar)
}
}
func (p *Pool) start() (err error) {
p.RefreshRate = DefaultRefreshRate
quit, err := lockEcho()
if err != nil {
return
}
p.quit = make(chan int)
go p.writer(quit)
return
}
func (p *Pool) writer(finish chan int) {
var first = true
for {
select {
case <-time.After(p.RefreshRate):
if p.print(first) {
p.print(false)
finish <- 1
return
}
first = false
case <-p.quit:
finish <- 1
return
}
}
}
func (p *Pool) print(first bool) bool {
var out string
if !first {
out = fmt.Sprintf("\033[%dA", len(p.bars))
}
isFinished := true
for _, bar := range p.bars {
if !bar.isFinish {
isFinished = false
}
bar.Update()
out += fmt.Sprintf("\r%s\n", bar.String())
}
fmt.Print(out)
return isFinished
}
// 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)
})
return unlockEcho()
}

View File

@ -0,0 +1,17 @@
package pb
import (
"regexp"
"unicode/utf8"
)
// Finds the control character sequences (like colors)
var ctrlFinder = regexp.MustCompile("\x1b\x5b[0-9]+\x6d")
func escapeAwareRuneCountInString(s string) int {
n := utf8.RuneCountInString(s)
for _, sm := range ctrlFinder.FindAllString(s, -1) {
n -= len(sm)
}
return n
}

View File

@ -0,0 +1,9 @@
// +build darwin freebsd netbsd openbsd dragonfly
// +build !appengine
package pb
import "syscall"
const ioctlReadTermios = syscall.TIOCGETA
const ioctlWriteTermios = syscall.TIOCSETA

View File

@ -0,0 +1,7 @@
// +build linux solaris
// +build !appengine
package pb
const ioctlReadTermios = 0x5401 // syscall.TCGETS
const ioctlWriteTermios = 0x5402 // syscall.TCSETS

View File

@ -21,9 +21,9 @@ import (
"os"
"time"
"github.com/coreos/etcd/Godeps/_workspace/src/github.com/cheggaaa/pb"
"github.com/coreos/etcd/Godeps/_workspace/src/github.com/spf13/cobra"
"github.com/coreos/etcd/Godeps/_workspace/src/golang.org/x/net/context"
"github.com/coreos/etcd/Godeps/_workspace/src/gopkg.in/cheggaaa/pb.v1"
v3 "github.com/coreos/etcd/clientv3"
)

View File

@ -19,9 +19,9 @@ import (
"os"
"time"
"github.com/coreos/etcd/Godeps/_workspace/src/github.com/cheggaaa/pb"
"github.com/coreos/etcd/Godeps/_workspace/src/github.com/spf13/cobra"
"github.com/coreos/etcd/Godeps/_workspace/src/golang.org/x/net/context"
"github.com/coreos/etcd/Godeps/_workspace/src/gopkg.in/cheggaaa/pb.v1"
v3 "github.com/coreos/etcd/clientv3"
)

View File

@ -17,8 +17,8 @@ package cmd
import (
"sync"
"github.com/coreos/etcd/Godeps/_workspace/src/github.com/cheggaaa/pb"
"github.com/coreos/etcd/Godeps/_workspace/src/github.com/spf13/cobra"
"github.com/coreos/etcd/Godeps/_workspace/src/gopkg.in/cheggaaa/pb.v1"
"github.com/coreos/etcd/pkg/transport"
)

View File

@ -21,9 +21,9 @@ import (
"os"
"time"
"github.com/coreos/etcd/Godeps/_workspace/src/github.com/cheggaaa/pb"
"github.com/coreos/etcd/Godeps/_workspace/src/github.com/spf13/cobra"
"github.com/coreos/etcd/Godeps/_workspace/src/golang.org/x/net/context"
"github.com/coreos/etcd/Godeps/_workspace/src/gopkg.in/cheggaaa/pb.v1"
v3 "github.com/coreos/etcd/clientv3"
v3sync "github.com/coreos/etcd/clientv3/concurrency"
)

View File

@ -24,9 +24,9 @@ import (
v3 "github.com/coreos/etcd/clientv3"
"github.com/coreos/etcd/Godeps/_workspace/src/github.com/cheggaaa/pb"
"github.com/coreos/etcd/Godeps/_workspace/src/github.com/spf13/cobra"
"github.com/coreos/etcd/Godeps/_workspace/src/golang.org/x/net/context"
"github.com/coreos/etcd/Godeps/_workspace/src/gopkg.in/cheggaaa/pb.v1"
)
// watchCmd represents the watch command