mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00
Godeps: semantic versioning cheggaaa/pb
Fix https://github.com/coreos/etcd/issues/4832.
This commit is contained in:
parent
e73ac5bdd7
commit
bb9a7f5a7c
13
Godeps/Godeps.json
generated
13
Godeps/Godeps.json
generated
@ -27,10 +27,6 @@
|
|||||||
"Comment": "v1.1.0-81-g0fd4c05",
|
"Comment": "v1.1.0-81-g0fd4c05",
|
||||||
"Rev": "0fd4c0547d204c7b1cad6db6f3adad5f2cf453e5"
|
"Rev": "0fd4c0547d204c7b1cad6db6f3adad5f2cf453e5"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"ImportPath": "github.com/cheggaaa/pb",
|
|
||||||
"Rev": "da1f27ad1d9509b16f65f52fd9d8138b0f2dc7b2"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/cockroachdb/cmux",
|
"ImportPath": "github.com/cockroachdb/cmux",
|
||||||
"Rev": "112f0506e7743d64a6eb8fedbcff13d9979bbf92"
|
"Rev": "112f0506e7743d64a6eb8fedbcff13d9979bbf92"
|
||||||
@ -119,10 +115,6 @@
|
|||||||
"ImportPath": "github.com/olekukonko/tablewriter",
|
"ImportPath": "github.com/olekukonko/tablewriter",
|
||||||
"Rev": "cca8bbc0798408af109aaaa239cbd2634846b340"
|
"Rev": "cca8bbc0798408af109aaaa239cbd2634846b340"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"ImportPath": "github.com/olekukonko/ts",
|
|
||||||
"Rev": "ecf753e7c962639ab5a1fb46f7da627d4c0a04b8"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"ImportPath": "github.com/prometheus/client_golang/prometheus",
|
"ImportPath": "github.com/prometheus/client_golang/prometheus",
|
||||||
"Comment": "0.7.0-52-ge51041b",
|
"Comment": "0.7.0-52-ge51041b",
|
||||||
@ -209,6 +201,11 @@
|
|||||||
{
|
{
|
||||||
"ImportPath": "google.golang.org/grpc",
|
"ImportPath": "google.golang.org/grpc",
|
||||||
"Rev": "b88c12e7caf74af3928de99a864aaa9916fa5aad"
|
"Rev": "b88c12e7caf74af3928de99a864aaa9916fa5aad"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ImportPath": "gopkg.in/cheggaaa/pb.v1",
|
||||||
|
"Comment": "v1.0.1",
|
||||||
|
"Rev": "29ad9b62f9e0274422d738242b94a5b89440bfa6"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
98
Godeps/_workspace/src/github.com/cheggaaa/pb/README.md
generated
vendored
98
Godeps/_workspace/src/github.com/cheggaaa/pb/README.md
generated
vendored
@ -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("<.- >")
|
|
||||||
```
|
|
||||||
81
Godeps/_workspace/src/github.com/cheggaaa/pb/example/copy/copy.go
generated
vendored
81
Godeps/_workspace/src/github.com/cheggaaa/pb/example/copy/copy.go
generated
vendored
@ -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]")
|
|
||||||
}
|
|
||||||
30
Godeps/_workspace/src/github.com/cheggaaa/pb/example/pb.go
generated
vendored
30
Godeps/_workspace/src/github.com/cheggaaa/pb/example/pb.go
generated
vendored
@ -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!")
|
|
||||||
}
|
|
||||||
45
Godeps/_workspace/src/github.com/cheggaaa/pb/format.go
generated
vendored
45
Godeps/_workspace/src/github.com/cheggaaa/pb/format.go
generated
vendored
@ -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
|
|
||||||
}
|
|
||||||
37
Godeps/_workspace/src/github.com/cheggaaa/pb/format_test.go
generated
vendored
37
Godeps/_workspace/src/github.com/cheggaaa/pb/format_test.go
generated
vendored
@ -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))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
7
Godeps/_workspace/src/github.com/cheggaaa/pb/pb_nix.go
generated
vendored
7
Godeps/_workspace/src/github.com/cheggaaa/pb/pb_nix.go
generated
vendored
@ -1,7 +0,0 @@
|
|||||||
// +build linux darwin freebsd netbsd openbsd
|
|
||||||
|
|
||||||
package pb
|
|
||||||
|
|
||||||
import "syscall"
|
|
||||||
|
|
||||||
const sys_ioctl = syscall.SYS_IOCTL
|
|
||||||
5
Godeps/_workspace/src/github.com/cheggaaa/pb/pb_solaris.go
generated
vendored
5
Godeps/_workspace/src/github.com/cheggaaa/pb/pb_solaris.go
generated
vendored
@ -1,5 +0,0 @@
|
|||||||
// +build solaris
|
|
||||||
|
|
||||||
package pb
|
|
||||||
|
|
||||||
const sys_ioctl = 54
|
|
||||||
37
Godeps/_workspace/src/github.com/cheggaaa/pb/pb_test.go
generated
vendored
37
Godeps/_workspace/src/github.com/cheggaaa/pb/pb_test.go
generated
vendored
@ -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()
|
|
||||||
}
|
|
||||||
16
Godeps/_workspace/src/github.com/cheggaaa/pb/pb_win.go
generated
vendored
16
Godeps/_workspace/src/github.com/cheggaaa/pb/pb_win.go
generated
vendored
@ -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
|
|
||||||
}
|
|
||||||
46
Godeps/_workspace/src/github.com/cheggaaa/pb/pb_x.go
generated
vendored
46
Godeps/_workspace/src/github.com/cheggaaa/pb/pb_x.go
generated
vendored
@ -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
|
|
||||||
}
|
|
||||||
6
Godeps/_workspace/src/github.com/olekukonko/ts/.travis.yml
generated
vendored
6
Godeps/_workspace/src/github.com/olekukonko/ts/.travis.yml
generated
vendored
@ -1,6 +0,0 @@
|
|||||||
language: go
|
|
||||||
|
|
||||||
go:
|
|
||||||
- 1.1
|
|
||||||
- 1.2
|
|
||||||
- tip
|
|
||||||
19
Godeps/_workspace/src/github.com/olekukonko/ts/LICENCE
generated
vendored
19
Godeps/_workspace/src/github.com/olekukonko/ts/LICENCE
generated
vendored
@ -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.
|
|
||||||
28
Godeps/_workspace/src/github.com/olekukonko/ts/README.md
generated
vendored
28
Godeps/_workspace/src/github.com/olekukonko/ts/README.md
generated
vendored
@ -1,28 +0,0 @@
|
|||||||
ts (Terminal Size)
|
|
||||||
==
|
|
||||||
|
|
||||||
[](https://travis-ci.org/olekukonko/ts) [](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)
|
|
||||||
36
Godeps/_workspace/src/github.com/olekukonko/ts/doc.go
generated
vendored
36
Godeps/_workspace/src/github.com/olekukonko/ts/doc.go
generated
vendored
@ -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
|
|
||||||
36
Godeps/_workspace/src/github.com/olekukonko/ts/ts.go
generated
vendored
36
Godeps/_workspace/src/github.com/olekukonko/ts/ts.go
generated
vendored
@ -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)
|
|
||||||
}
|
|
||||||
14
Godeps/_workspace/src/github.com/olekukonko/ts/ts_darwin.go
generated
vendored
14
Godeps/_workspace/src/github.com/olekukonko/ts/ts_darwin.go
generated
vendored
@ -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
|
|
||||||
)
|
|
||||||
13
Godeps/_workspace/src/github.com/olekukonko/ts/ts_linux.go
generated
vendored
13
Godeps/_workspace/src/github.com/olekukonko/ts/ts_linux.go
generated
vendored
@ -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
|
|
||||||
)
|
|
||||||
14
Godeps/_workspace/src/github.com/olekukonko/ts/ts_other.go
generated
vendored
14
Godeps/_workspace/src/github.com/olekukonko/ts/ts_other.go
generated
vendored
@ -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
|
|
||||||
)
|
|
||||||
32
Godeps/_workspace/src/github.com/olekukonko/ts/ts_test.go
generated
vendored
32
Godeps/_workspace/src/github.com/olekukonko/ts/ts_test.go
generated
vendored
@ -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")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
14
Godeps/_workspace/src/github.com/olekukonko/ts/ts_unix.go
generated
vendored
14
Godeps/_workspace/src/github.com/olekukonko/ts/ts_unix.go
generated
vendored
@ -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
|
|
||||||
)
|
|
||||||
64
Godeps/_workspace/src/github.com/olekukonko/ts/ts_windows.go
generated
vendored
64
Godeps/_workspace/src/github.com/olekukonko/ts/ts_windows.go
generated
vendored
@ -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
|
|
||||||
}
|
|
||||||
46
Godeps/_workspace/src/github.com/olekukonko/ts/ts_x.go
generated
vendored
46
Godeps/_workspace/src/github.com/olekukonko/ts/ts_x.go
generated
vendored
@ -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
|
|
||||||
}
|
|
||||||
@ -2,3 +2,6 @@ language: go
|
|||||||
go:
|
go:
|
||||||
- 1.4.2
|
- 1.4.2
|
||||||
sudo: false
|
sudo: false
|
||||||
|
os:
|
||||||
|
- linux
|
||||||
|
- osx
|
||||||
@ -1,4 +1,4 @@
|
|||||||
Copyright (c) 2012, Sergey Cherepanov
|
Copyright (c) 2012-2015, Sergey Cherepanov
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
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
176
Godeps/_workspace/src/gopkg.in/cheggaaa/pb.v1/README.md
generated
vendored
Normal 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
|
||||||
|
```
|
||||||
87
Godeps/_workspace/src/gopkg.in/cheggaaa/pb.v1/format.go
generated
vendored
Normal file
87
Godeps/_workspace/src/gopkg.in/cheggaaa/pb.v1/format.go
generated
vendored
Normal 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
|
||||||
|
}
|
||||||
@ -1,3 +1,4 @@
|
|||||||
|
// Simple console progress bars
|
||||||
package pb
|
package pb
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@ -11,6 +12,9 @@ import (
|
|||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Current version
|
||||||
|
const Version = "1.0.1"
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// Default refresh rate - 200ms
|
// Default refresh rate - 200ms
|
||||||
DEFAULT_REFRESH_RATE = time.Millisecond * 200
|
DEFAULT_REFRESH_RATE = time.Millisecond * 200
|
||||||
@ -30,7 +34,7 @@ func New(total int) *ProgressBar {
|
|||||||
return New64(int64(total))
|
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 {
|
func New64(total int64) *ProgressBar {
|
||||||
pb := &ProgressBar{
|
pb := &ProgressBar{
|
||||||
Total: total,
|
Total: total,
|
||||||
@ -42,8 +46,9 @@ func New64(total int64) *ProgressBar {
|
|||||||
ShowFinalTime: true,
|
ShowFinalTime: true,
|
||||||
Units: U_NO,
|
Units: U_NO,
|
||||||
ManualUpdate: false,
|
ManualUpdate: false,
|
||||||
isFinish: make(chan struct{}),
|
finish: make(chan struct{}),
|
||||||
currentValue: -1,
|
currentValue: -1,
|
||||||
|
mu: new(sync.Mutex),
|
||||||
}
|
}
|
||||||
return pb.Format(FORMAT)
|
return pb.Format(FORMAT)
|
||||||
}
|
}
|
||||||
@ -77,8 +82,13 @@ type ProgressBar struct {
|
|||||||
ForceWidth bool
|
ForceWidth bool
|
||||||
ManualUpdate bool
|
ManualUpdate bool
|
||||||
|
|
||||||
|
// Default width for the time box.
|
||||||
|
UnitsWidth int
|
||||||
|
TimeBoxWidth int
|
||||||
|
|
||||||
finishOnce sync.Once //Guards isFinish
|
finishOnce sync.Once //Guards isFinish
|
||||||
isFinish chan struct{}
|
finish chan struct{}
|
||||||
|
isFinish bool
|
||||||
|
|
||||||
startTime time.Time
|
startTime time.Time
|
||||||
startValue int64
|
startValue int64
|
||||||
@ -86,11 +96,16 @@ type ProgressBar struct {
|
|||||||
|
|
||||||
prefix, postfix string
|
prefix, postfix string
|
||||||
|
|
||||||
|
mu *sync.Mutex
|
||||||
|
lastPrint string
|
||||||
|
|
||||||
BarStart string
|
BarStart string
|
||||||
BarEnd string
|
BarEnd string
|
||||||
Empty string
|
Empty string
|
||||||
Current string
|
Current string
|
||||||
CurrentN string
|
CurrentN string
|
||||||
|
|
||||||
|
AlwaysUpdate bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start print
|
// Start print
|
||||||
@ -102,7 +117,8 @@ func (pb *ProgressBar) Start() *ProgressBar {
|
|||||||
pb.ShowPercent = false
|
pb.ShowPercent = false
|
||||||
}
|
}
|
||||||
if !pb.ManualUpdate {
|
if !pb.ManualUpdate {
|
||||||
go pb.writer()
|
pb.Update() // Initial printing of the bar before running the bar refresher.
|
||||||
|
go pb.refresher()
|
||||||
}
|
}
|
||||||
return pb
|
return pb
|
||||||
}
|
}
|
||||||
@ -146,8 +162,14 @@ func (pb *ProgressBar) Postfix(postfix string) *ProgressBar {
|
|||||||
|
|
||||||
// Set custom format for bar
|
// Set custom format for bar
|
||||||
// Example: bar.Format("[=>_]")
|
// Example: bar.Format("[=>_]")
|
||||||
|
// Example: bar.Format("[\x00=\x00>\x00-\x00]") // \x00 is the delimiter
|
||||||
func (pb *ProgressBar) Format(format string) *ProgressBar {
|
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 {
|
if len(formatEntries) == 5 {
|
||||||
pb.BarStart = formatEntries[0]
|
pb.BarStart = formatEntries[0]
|
||||||
pb.BarEnd = formatEntries[4]
|
pb.BarEnd = formatEntries[4]
|
||||||
@ -190,11 +212,12 @@ func (pb *ProgressBar) SetWidth(width int) *ProgressBar {
|
|||||||
func (pb *ProgressBar) Finish() {
|
func (pb *ProgressBar) Finish() {
|
||||||
//Protect multiple calls
|
//Protect multiple calls
|
||||||
pb.finishOnce.Do(func() {
|
pb.finishOnce.Do(func() {
|
||||||
close(pb.isFinish)
|
close(pb.finish)
|
||||||
pb.write(atomic.LoadInt64(&pb.current))
|
pb.write(atomic.LoadInt64(&pb.current))
|
||||||
if !pb.NotPrint {
|
if !pb.NotPrint {
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
}
|
}
|
||||||
|
pb.isFinish = true
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -230,16 +253,23 @@ func (pb *ProgressBar) write(current int64) {
|
|||||||
|
|
||||||
// percents
|
// percents
|
||||||
if pb.ShowPercent {
|
if pb.ShowPercent {
|
||||||
percent := float64(current) / (float64(pb.Total) / float64(100))
|
var percent float64
|
||||||
percentBox = fmt.Sprintf(" %.02f %% ", percent)
|
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
|
// counters
|
||||||
if pb.ShowCounters {
|
if pb.ShowCounters {
|
||||||
|
current := Format(current).To(pb.Units).Width(pb.UnitsWidth)
|
||||||
if pb.Total > 0 {
|
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 {
|
} 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)
|
fromStart := time.Now().Sub(pb.startTime)
|
||||||
currentFromStart := current - pb.startValue
|
currentFromStart := current - pb.startValue
|
||||||
select {
|
select {
|
||||||
case <-pb.isFinish:
|
case <-pb.finish:
|
||||||
if pb.ShowFinalTime {
|
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()
|
timeLeftBox = left.String()
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
if pb.ShowTimeLeft && currentFromStart > 0 {
|
if pb.ShowTimeLeft && currentFromStart > 0 {
|
||||||
perEntry := fromStart / time.Duration(currentFromStart)
|
perEntry := fromStart / time.Duration(currentFromStart)
|
||||||
left := time.Duration(pb.Total-currentFromStart) * perEntry
|
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
|
left = (left / time.Second) * time.Second
|
||||||
timeLeftBox = left.String()
|
|
||||||
}
|
}
|
||||||
|
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
|
// speed
|
||||||
if pb.ShowSpeed && currentFromStart > 0 {
|
if pb.ShowSpeed && currentFromStart > 0 {
|
||||||
fromStart := time.Now().Sub(pb.startTime)
|
fromStart := time.Now().Sub(pb.startTime)
|
||||||
speed := float64(currentFromStart) / (float64(fromStart) / float64(time.Second))
|
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
|
// bar
|
||||||
if pb.ShowBar {
|
if pb.ShowBar {
|
||||||
size := width - barWidth
|
size := width - barWidth
|
||||||
@ -288,10 +334,8 @@ func (pb *ProgressBar) write(current int64) {
|
|||||||
} else if curCount > 0 {
|
} else if curCount > 0 {
|
||||||
barBox += strings.Repeat(pb.Current, curCount-1) + pb.CurrentN
|
barBox += strings.Repeat(pb.Current, curCount-1) + pb.CurrentN
|
||||||
}
|
}
|
||||||
|
|
||||||
barBox += strings.Repeat(pb.Empty, emptCount) + pb.BarEnd
|
barBox += strings.Repeat(pb.Empty, emptCount) + pb.BarEnd
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
barBox = pb.BarStart
|
barBox = pb.BarStart
|
||||||
pos := size - int(current)%int(size)
|
pos := size - int(current)%int(size)
|
||||||
if pos-1 > 0 {
|
if pos-1 > 0 {
|
||||||
@ -308,12 +352,17 @@ func (pb *ProgressBar) write(current int64) {
|
|||||||
|
|
||||||
// check len
|
// check len
|
||||||
out = pb.prefix + countersBox + barBox + percentBox + speedBox + timeLeftBox + pb.postfix
|
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))
|
end = strings.Repeat(" ", width-utf8.RuneCountInString(out))
|
||||||
}
|
}
|
||||||
|
|
||||||
// and print!
|
// and print!
|
||||||
|
pb.mu.Lock()
|
||||||
|
pb.lastPrint = out + end
|
||||||
|
pb.mu.Unlock()
|
||||||
switch {
|
switch {
|
||||||
|
case pb.isFinish:
|
||||||
|
return
|
||||||
case pb.Output != nil:
|
case pb.Output != nil:
|
||||||
fmt.Fprint(pb.Output, "\r"+out+end)
|
fmt.Fprint(pb.Output, "\r"+out+end)
|
||||||
case pb.Callback != nil:
|
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 {
|
func (pb *ProgressBar) GetWidth() int {
|
||||||
if pb.ForceWidth {
|
if pb.ForceWidth {
|
||||||
return pb.Width
|
return pb.Width
|
||||||
@ -340,18 +394,21 @@ func (pb *ProgressBar) GetWidth() int {
|
|||||||
// Write the current state of the progressbar
|
// Write the current state of the progressbar
|
||||||
func (pb *ProgressBar) Update() {
|
func (pb *ProgressBar) Update() {
|
||||||
c := atomic.LoadInt64(&pb.current)
|
c := atomic.LoadInt64(&pb.current)
|
||||||
if c != pb.currentValue {
|
if pb.AlwaysUpdate || c != pb.currentValue {
|
||||||
pb.write(c)
|
pb.write(c)
|
||||||
pb.currentValue = c
|
pb.currentValue = c
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Internal loop for writing progressbar
|
func (pb *ProgressBar) String() string {
|
||||||
func (pb *ProgressBar) writer() {
|
return pb.lastPrint
|
||||||
pb.Update()
|
}
|
||||||
|
|
||||||
|
// Internal loop for refreshing the progressbar
|
||||||
|
func (pb *ProgressBar) refresher() {
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-pb.isFinish:
|
case <-pb.finish:
|
||||||
return
|
return
|
||||||
case <-time.After(pb.RefreshRate):
|
case <-time.After(pb.RefreshRate):
|
||||||
pb.Update()
|
pb.Update()
|
||||||
11
Godeps/_workspace/src/gopkg.in/cheggaaa/pb.v1/pb_appengine.go
generated
vendored
Normal file
11
Godeps/_workspace/src/gopkg.in/cheggaaa/pb.v1/pb_appengine.go
generated
vendored
Normal 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")
|
||||||
|
}
|
||||||
8
Godeps/_workspace/src/gopkg.in/cheggaaa/pb.v1/pb_nix.go
generated
vendored
Normal file
8
Godeps/_workspace/src/gopkg.in/cheggaaa/pb.v1/pb_nix.go
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
// +build linux darwin freebsd netbsd openbsd dragonfly
|
||||||
|
// +build !appengine
|
||||||
|
|
||||||
|
package pb
|
||||||
|
|
||||||
|
import "syscall"
|
||||||
|
|
||||||
|
const sysIoctl = syscall.SYS_IOCTL
|
||||||
6
Godeps/_workspace/src/gopkg.in/cheggaaa/pb.v1/pb_solaris.go
generated
vendored
Normal file
6
Godeps/_workspace/src/gopkg.in/cheggaaa/pb.v1/pb_solaris.go
generated
vendored
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
// +build solaris
|
||||||
|
// +build !appengine
|
||||||
|
|
||||||
|
package pb
|
||||||
|
|
||||||
|
const sysIoctl = 54
|
||||||
61
Godeps/_workspace/src/gopkg.in/cheggaaa/pb.v1/pb_win.go
generated
vendored
Normal file
61
Godeps/_workspace/src/gopkg.in/cheggaaa/pb.v1/pb_win.go
generated
vendored
Normal 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
110
Godeps/_workspace/src/gopkg.in/cheggaaa/pb.v1/pb_x.go
generated
vendored
Normal 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
93
Godeps/_workspace/src/gopkg.in/cheggaaa/pb.v1/pool.go
generated
vendored
Normal 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()
|
||||||
|
}
|
||||||
17
Godeps/_workspace/src/gopkg.in/cheggaaa/pb.v1/runecount.go
generated
vendored
Normal file
17
Godeps/_workspace/src/gopkg.in/cheggaaa/pb.v1/runecount.go
generated
vendored
Normal 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
|
||||||
|
}
|
||||||
9
Godeps/_workspace/src/gopkg.in/cheggaaa/pb.v1/termios_bsd.go
generated
vendored
Normal file
9
Godeps/_workspace/src/gopkg.in/cheggaaa/pb.v1/termios_bsd.go
generated
vendored
Normal 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
|
||||||
7
Godeps/_workspace/src/gopkg.in/cheggaaa/pb.v1/termios_nix.go
generated
vendored
Normal file
7
Godeps/_workspace/src/gopkg.in/cheggaaa/pb.v1/termios_nix.go
generated
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
// +build linux solaris
|
||||||
|
// +build !appengine
|
||||||
|
|
||||||
|
package pb
|
||||||
|
|
||||||
|
const ioctlReadTermios = 0x5401 // syscall.TCGETS
|
||||||
|
const ioctlWriteTermios = 0x5402 // syscall.TCSETS
|
||||||
@ -21,9 +21,9 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"time"
|
"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/github.com/spf13/cobra"
|
||||||
"github.com/coreos/etcd/Godeps/_workspace/src/golang.org/x/net/context"
|
"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"
|
v3 "github.com/coreos/etcd/clientv3"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@ -19,9 +19,9 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"time"
|
"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/github.com/spf13/cobra"
|
||||||
"github.com/coreos/etcd/Godeps/_workspace/src/golang.org/x/net/context"
|
"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"
|
v3 "github.com/coreos/etcd/clientv3"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@ -17,8 +17,8 @@ package cmd
|
|||||||
import (
|
import (
|
||||||
"sync"
|
"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/github.com/spf13/cobra"
|
||||||
|
"github.com/coreos/etcd/Godeps/_workspace/src/gopkg.in/cheggaaa/pb.v1"
|
||||||
"github.com/coreos/etcd/pkg/transport"
|
"github.com/coreos/etcd/pkg/transport"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@ -21,9 +21,9 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"time"
|
"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/github.com/spf13/cobra"
|
||||||
"github.com/coreos/etcd/Godeps/_workspace/src/golang.org/x/net/context"
|
"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"
|
v3 "github.com/coreos/etcd/clientv3"
|
||||||
v3sync "github.com/coreos/etcd/clientv3/concurrency"
|
v3sync "github.com/coreos/etcd/clientv3/concurrency"
|
||||||
)
|
)
|
||||||
|
|||||||
@ -24,9 +24,9 @@ import (
|
|||||||
|
|
||||||
v3 "github.com/coreos/etcd/clientv3"
|
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/github.com/spf13/cobra"
|
||||||
"github.com/coreos/etcd/Godeps/_workspace/src/golang.org/x/net/context"
|
"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
|
// watchCmd represents the watch command
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user