From 08eb5b42eb8d82a64054cc1df75d84ca6cc6a3a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20St=C3=BCrtz?= Date: Sun, 21 Aug 2016 22:38:22 +0200 Subject: [PATCH] Fix progress output on Windows The windows cmd shell is not aware of ANSI escape sequences and does print them uninterpreted to the console. This is ugly. Added a function to generate platform specific string for the escape sequence. On Windows this will be 79 white spaces with a trailing \r. --- src/cmds/restic/cleanup.go | 2 +- src/cmds/restic/cmd_backup.go | 10 +++++----- src/cmds/restic/cmd_check.go | 2 +- src/cmds/restic/cmd_prune.go | 2 +- src/cmds/restic/global.go | 11 +++++++++++ 5 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/cmds/restic/cleanup.go b/src/cmds/restic/cleanup.go index 32caef7b8..c2072650a 100644 --- a/src/cmds/restic/cleanup.go +++ b/src/cmds/restic/cleanup.go @@ -57,7 +57,7 @@ func RunCleanupHandlers() { func CleanupHandler(c <-chan os.Signal) { for s := range c { debug.Log("CleanupHandler", "signal %v received, cleaning up", s) - fmt.Println("\x1b[2KInterrupt received, cleaning up") + fmt.Printf("%sInterrupt received, cleaning up\n", ClearLine()) RunCleanupHandlers() fmt.Println("exiting") os.Exit(0) diff --git a/src/cmds/restic/cmd_backup.go b/src/cmds/restic/cmd_backup.go index 660200094..26fb19015 100644 --- a/src/cmds/restic/cmd_backup.go +++ b/src/cmds/restic/cmd_backup.go @@ -114,10 +114,10 @@ func (cmd CmdBackup) newScanProgress() *restic.Progress { p := restic.NewProgress(time.Second) p.OnUpdate = func(s restic.Stat, d time.Duration, ticker bool) { - fmt.Printf("\x1b[2K[%s] %d directories, %d files, %s\r", formatDuration(d), s.Dirs, s.Files, formatBytes(s.Bytes)) + fmt.Printf("%s[%s] %d directories, %d files, %s\r", ClearLine(), formatDuration(d), s.Dirs, s.Files, formatBytes(s.Bytes)) } p.OnDone = func(s restic.Stat, d time.Duration, ticker bool) { - fmt.Printf("\x1b[2Kscanned %d directories, %d files in %s\n", s.Dirs, s.Files, formatDuration(d)) + fmt.Printf("%sscanned %d directories, %d files in %s\n", ClearLine(), s.Dirs, s.Files, formatDuration(d)) } return p @@ -167,7 +167,7 @@ func (cmd CmdBackup) newArchiveProgress(todo restic.Stat) *restic.Progress { } } - fmt.Printf("\x1b[2K%s%s\r", status1, status2) + fmt.Printf("%s%s%s\r", ClearLine(), status1, status2) } archiveProgress.OnDone = func(s restic.Stat, d time.Duration, ticker bool) { @@ -208,7 +208,7 @@ func (cmd CmdBackup) newArchiveStdinProgress() *restic.Progress { } } - fmt.Printf("\x1b[2K%s\r", status1) + fmt.Printf("%s%s\r", ClearLine(), status1) } archiveProgress.OnDone = func(s restic.Stat, d time.Duration, ticker bool) { @@ -375,7 +375,7 @@ func (cmd CmdBackup) Execute(args []string) error { arch.Error = func(dir string, fi os.FileInfo, err error) error { // TODO: make ignoring errors configurable - cmd.global.Warnf("\x1b[2K\rerror for %s: %v\n", dir, err) + cmd.global.Warnf("%s\rerror for %s: %v\n", ClearLine(), dir, err) return nil } diff --git a/src/cmds/restic/cmd_check.go b/src/cmds/restic/cmd_check.go index 25e3ff325..9609f4283 100644 --- a/src/cmds/restic/cmd_check.go +++ b/src/cmds/restic/cmd_check.go @@ -54,7 +54,7 @@ func (cmd CmdCheck) newReadProgress(todo restic.Stat) *restic.Progress { } } - fmt.Printf("\x1b[2K%s\r", status) + fmt.Printf("%s%s\r", ClearLine(), status) } readProgress.OnDone = func(s restic.Stat, d time.Duration, ticker bool) { diff --git a/src/cmds/restic/cmd_prune.go b/src/cmds/restic/cmd_prune.go index a2aa6451d..cdc83a17f 100644 --- a/src/cmds/restic/cmd_prune.go +++ b/src/cmds/restic/cmd_prune.go @@ -55,7 +55,7 @@ func newProgressMax(show bool, max uint64, description string) *restic.Progress } } - fmt.Printf("\x1b[2K%s\r", status) + fmt.Printf("%s%s\r", ClearLine(), status) } p.OnDone = func(s restic.Stat, d time.Duration, ticker bool) { diff --git a/src/cmds/restic/global.go b/src/cmds/restic/global.go index 7d0df2adf..2c14baf9e 100644 --- a/src/cmds/restic/global.go +++ b/src/cmds/restic/global.go @@ -5,6 +5,7 @@ import ( "fmt" "io" "os" + "runtime" "strings" "syscall" @@ -82,6 +83,16 @@ func restoreTerminal() { var globalOpts = GlobalOptions{stdout: os.Stdout, stderr: os.Stderr} var parser = flags.NewParser(&globalOpts, flags.HelpFlag|flags.PassDoubleDash) +// Clear Line ASCII sequence is invalid on Windows so ignore it here +func ClearLine() string { + if runtime.GOOS == "windows" { + // Ugly Workaround, write 79 Whitespaces and return + return " \r" + } else { + return "\x1b[2K" + } +} + // Printf writes the message to the configured stdout stream. func (o GlobalOptions) Printf(format string, args ...interface{}) { _, err := fmt.Fprintf(o.stdout, format, args...)