Compare commits

...

1 Commits

Author SHA1 Message Date
Jan Broer
b477c261e5 CLI progress indicator, initial import
Signed-off-by: Jan Broer <janeczku@yahoo.de>
2015-05-21 22:54:39 +02:00
4 changed files with 158 additions and 1 deletions

View File

@@ -109,6 +109,8 @@ func ValidateHostName(name string) bool {
func (h *Host) Create(name string) error {
// create the instance
log.Progress.Start("Creating the instance")
defer log.Progress.Stop()
if err := h.Driver.Create(); err != nil {
return err
}
@@ -120,6 +122,7 @@ func (h *Host) Create(name string) error {
// TODO: Not really a fan of just checking "none" here.
if h.Driver.DriverName() != "none" {
log.Progress.Start("Waiting for instance to come up")
if err := WaitForSSH(h); err != nil {
return err
}
@@ -129,6 +132,7 @@ func (h *Host) Create(name string) error {
return err
}
log.Progress.Start("Provisioning the instance")
if err := provisioner.Provision(*h.HostOptions.SwarmOptions, *h.HostOptions.AuthOptions, *h.HostOptions.EngineOptions); err != nil {
return err
}
@@ -252,6 +256,8 @@ func (h *Host) Upgrade() error {
}
func (h *Host) Remove(force bool) error {
log.Progress.Start("Removing the instance")
defer log.Progress.Stop()
if err := h.Driver.Remove(); err != nil {
if !force {
return err

View File

@@ -36,7 +36,8 @@ type Logger interface {
}
var (
l = TerminalLogger{}
l = TerminalLogger{}
Progress = NewProgress()
)
// TODO: I think this is superflous and can be replaced by one check for if

142
log/progress.go Normal file
View File

@@ -0,0 +1,142 @@
package log
import (
"os"
"strings"
"time"
"github.com/docker/docker/pkg/term"
)
type Progressor struct {
title string
stopChan chan bool
isActive bool
isTerminal bool
withColor bool
termWidth int
clearBuffer []byte
}
func NewProgress() *Progressor {
var (
isTerminal = false
withColor = false
termWidth int
clearBuffer []byte
)
fd := os.Stdout.Fd()
isTerminal = term.IsTerminal(fd)
if isTerminal {
winsize, err := term.GetWinsize(fd)
if err != nil {
termWidth = 80
} else {
termWidth = int(winsize.Width)
}
if isColorTerminal() {
withColor = true
}
clearBuffer = make([]byte, termWidth)
for i := range clearBuffer {
copy(clearBuffer[i:], " ")
}
copy(clearBuffer[0:], "\r")
}
return &Progressor{
stopChan: make(chan bool, 1),
isActive: false,
isTerminal: isTerminal,
withColor: withColor,
termWidth: termWidth,
clearBuffer: clearBuffer,
}
}
// invoke with: 'log.Progress.Start("some description")'
func (p *Progressor) Start(msg string) {
if !p.isTerminal || isDebug() {
Info(msg)
return
}
// stop current progress
if p.isActive {
p.Stop()
}
p.title = msg
p.isActive = true
go p.writer()
}
// invoke with: 'log.Progress.Stop()'
func (p *Progressor) Stop() {
if p.isActive {
p.stopChan <- true
p.isActive = false
// variant a - remove progress
os.Stdout.Write(p.clearBuffer)
os.Stdout.Write([]byte("\r"))
os.Stdout.Sync()
// variant b - keep progress and prefix with "+"
//os.Stdout.Write([]byte("\r+\n"))
//os.Stdout.Sync()
}
}
// write out progress in a loop
func (p *Progressor) writer() {
for {
select {
case <-p.stopChan:
return
default:
var out string
charset := []string{"|", "/", "-", "\\"}
for i := 0; i < len(charset); i++ {
out = charset[i]
if p.withColor {
out = "\x1b[1;32m" + charset[i] + "\x1b[0m"
}
os.Stdout.Write([]byte("\r" + out + " " + p.title))
os.Stdout.Sync()
time.Sleep(time.Millisecond * 150)
}
}
}
}
func isColorTerminal() bool {
matches := []string{
"Eterm",
"ansi",
"color",
"console",
"cygwin",
"dtterm",
"eterm-color",
"gnome",
"konsole",
"kterm",
"linux",
"mach-color",
"mlterm",
"putty",
"rxvt",
"screen",
"vt100",
"xterm",
}
if os.Getenv("COLORTERM") != "" {
return true
}
term := os.Getenv("TERM")
if term == "dumb" {
return false
}
for _, name := range matches {
if strings.Contains(term, name) {
return true
}
}
return false
}

View File

@@ -12,12 +12,20 @@ type TerminalLogger struct {
}
func (t TerminalLogger) log(args ...interface{}) {
if Progress.isActive {
Progress.Stop()
defer Progress.Start(Progress.title)
}
fmt.Print(args...)
fmt.Print(t.fieldOut, "\n")
t.fieldOut = ""
}
func (t TerminalLogger) logf(fmtString string, args ...interface{}) {
if Progress.isActive {
Progress.Stop()
defer Progress.Start(Progress.title)
}
fmt.Printf(fmtString, args...)
fmt.Print(t.fieldOut, "\n")
t.fieldOut = ""