Merge pull request #585 from trbs/progress_without_terminal

show progress every second when run non interactively
This commit is contained in:
Alexander Neumann
2016-08-27 10:10:18 +02:00
7 changed files with 94 additions and 24 deletions

View File

@@ -112,12 +112,12 @@ func (cmd CmdBackup) newScanProgress() *restic.Progress {
return nil
}
p := restic.NewProgress(time.Second)
p := restic.NewProgress()
p.OnUpdate = func(s restic.Stat, d time.Duration, ticker bool) {
fmt.Printf("%s[%s] %d directories, %d files, %s\r", ClearLine(), formatDuration(d), s.Dirs, s.Files, formatBytes(s.Bytes))
PrintProgress("[%s] %d directories, %d files, %s", formatDuration(d), s.Dirs, s.Files, formatBytes(s.Bytes))
}
p.OnDone = func(s restic.Stat, d time.Duration, ticker bool) {
fmt.Printf("%sscanned %d directories, %d files in %s\n", ClearLine(), s.Dirs, s.Files, formatDuration(d))
PrintProgress("scanned %d directories, %d files in %s\n", s.Dirs, s.Files, formatDuration(d))
}
return p
@@ -128,7 +128,7 @@ func (cmd CmdBackup) newArchiveProgress(todo restic.Stat) *restic.Progress {
return nil
}
archiveProgress := restic.NewProgress(time.Second)
archiveProgress := restic.NewProgress()
var bps, eta uint64
itemsTodo := todo.Files + todo.Dirs
@@ -167,7 +167,7 @@ func (cmd CmdBackup) newArchiveProgress(todo restic.Stat) *restic.Progress {
}
}
fmt.Printf("%s%s%s\r", ClearLine(), status1, status2)
PrintProgress("%s%s", status1, status2)
}
archiveProgress.OnDone = func(s restic.Stat, d time.Duration, ticker bool) {
@@ -182,7 +182,7 @@ func (cmd CmdBackup) newArchiveStdinProgress() *restic.Progress {
return nil
}
archiveProgress := restic.NewProgress(time.Second)
archiveProgress := restic.NewProgress()
var bps uint64
@@ -208,7 +208,7 @@ func (cmd CmdBackup) newArchiveStdinProgress() *restic.Progress {
}
}
fmt.Printf("%s%s\r", ClearLine(), status1)
PrintProgress("%s%s", status1)
}
archiveProgress.OnDone = func(s restic.Stat, d time.Duration, ticker bool) {

View File

@@ -38,7 +38,7 @@ func (cmd CmdCheck) newReadProgress(todo restic.Stat) *restic.Progress {
return nil
}
readProgress := restic.NewProgress(time.Second)
readProgress := restic.NewProgress()
readProgress.OnUpdate = func(s restic.Stat, d time.Duration, ticker bool) {
status := fmt.Sprintf("[%s] %s %d / %d items",
@@ -54,7 +54,7 @@ func (cmd CmdCheck) newReadProgress(todo restic.Stat) *restic.Progress {
}
}
fmt.Printf("%s%s\r", ClearLine(), status)
PrintProgress("%s", status)
}
readProgress.OnDone = func(s restic.Stat, d time.Duration, ticker bool) {

View File

@@ -39,7 +39,7 @@ func newProgressMax(show bool, max uint64, description string) *restic.Progress
return nil
}
p := restic.NewProgress(time.Second)
p := restic.NewProgress()
p.OnUpdate = func(s restic.Stat, d time.Duration, ticker bool) {
status := fmt.Sprintf("[%s] %s %d / %d %s",
@@ -55,7 +55,7 @@ func newProgressMax(show bool, max uint64, description string) *restic.Progress
}
}
fmt.Printf("%s%s\r", ClearLine(), status)
PrintProgress("%s", status)
}
p.OnDone = func(s restic.Stat, d time.Duration, ticker bool) {

View File

@@ -24,6 +24,7 @@ import (
var version = "compiled manually"
var compiledAt = "unknown time"
var isTerminal = terminal.IsTerminal(int(os.Stdout.Fd()))
// GlobalOptions holds all those options that can be set for every command.
type GlobalOptions struct {
@@ -60,11 +61,11 @@ func checkErrno(err error) error {
// restoreTerminal installs a cleanup handler that restores the previous
// terminal state on exit.
func restoreTerminal() {
fd := int(os.Stdout.Fd())
if !terminal.IsTerminal(fd) {
if !isTerminal {
return
}
fd := int(os.Stdout.Fd())
state, err := terminal.GetState(fd)
if err != nil {
fmt.Fprintf(os.Stderr, "unable to get terminal state: %v\n", err)
@@ -116,17 +117,38 @@ func (o GlobalOptions) Verbosef(format string, args ...interface{}) {
}
// ShowProgress returns true iff the progress status should be written, i.e.
// the quiet flag is not set and the output is a terminal.
// the quiet flag is not set.
func (o GlobalOptions) ShowProgress() bool {
if o.Quiet {
return false
}
if !terminal.IsTerminal(int(os.Stdout.Fd())) {
return false
return true
}
// PrintProgress wraps fmt.Printf to handle the difference in writing progress
// information to terminals and non-terminal stdout
func PrintProgress(format string, args ...interface{}) {
var (
message string
carriageControl string
)
message = fmt.Sprintf(format, args...)
if !(strings.HasSuffix(message, "\r") || strings.HasSuffix(message, "\n")) {
if isTerminal {
carriageControl = "\r"
} else {
carriageControl = "\n"
}
message = fmt.Sprintf("%s%s", message, carriageControl)
}
return true
if isTerminal {
message = fmt.Sprintf("%s%s", ClearLine(), message)
}
fmt.Print(message)
}
// Warnf writes the message to the configured stderr stream.
@@ -183,7 +205,7 @@ func (o GlobalOptions) ReadPassword(prompt string) string {
err error
)
if terminal.IsTerminal(int(os.Stdin.Fd())) {
if isTerminal {
password, err = readPasswordTerminal(os.Stdin, os.Stderr, prompt)
} else {
password, err = readPassword(os.Stdin)