mirror of
https://github.com/octoleo/restic.git
synced 2024-11-22 21:05:10 +00:00
ui: consolidate backup ui in ui/backup package
This commit is contained in:
parent
503d4c3e2f
commit
fbb0e6499a
@ -24,8 +24,7 @@ import (
|
|||||||
"github.com/restic/restic/internal/repository"
|
"github.com/restic/restic/internal/repository"
|
||||||
"github.com/restic/restic/internal/restic"
|
"github.com/restic/restic/internal/restic"
|
||||||
"github.com/restic/restic/internal/textfile"
|
"github.com/restic/restic/internal/textfile"
|
||||||
"github.com/restic/restic/internal/ui"
|
"github.com/restic/restic/internal/ui/backup"
|
||||||
"github.com/restic/restic/internal/ui/json"
|
|
||||||
"github.com/restic/restic/internal/ui/termstatus"
|
"github.com/restic/restic/internal/ui/termstatus"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -527,13 +526,13 @@ func runBackup(opts BackupOptions, gopts GlobalOptions, term *termstatus.Termina
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
var progressPrinter ui.ProgressPrinter
|
var progressPrinter backup.ProgressPrinter
|
||||||
if gopts.JSON {
|
if gopts.JSON {
|
||||||
progressPrinter = json.NewBackup(term, gopts.verbosity)
|
progressPrinter = backup.NewJSONProgress(term, gopts.verbosity)
|
||||||
} else {
|
} else {
|
||||||
progressPrinter = ui.NewBackup(term, gopts.verbosity)
|
progressPrinter = backup.NewTextProgress(term, gopts.verbosity)
|
||||||
}
|
}
|
||||||
progressReporter := ui.NewProgress(progressPrinter)
|
progressReporter := backup.NewProgress(progressPrinter)
|
||||||
|
|
||||||
if opts.DryRun {
|
if opts.DryRun {
|
||||||
repo.SetDryRun()
|
repo.SetDryRun()
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package json
|
package backup
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
@ -13,8 +13,8 @@ import (
|
|||||||
"github.com/restic/restic/internal/ui/termstatus"
|
"github.com/restic/restic/internal/ui/termstatus"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Backup reports progress for the `backup` command in JSON.
|
// JSONProgress reports progress for the `backup` command in JSON.
|
||||||
type Backup struct {
|
type JSONProgress struct {
|
||||||
*ui.Message
|
*ui.Message
|
||||||
*ui.StdioWrapper
|
*ui.StdioWrapper
|
||||||
|
|
||||||
@ -23,11 +23,11 @@ type Backup struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// assert that Backup implements the ProgressPrinter interface
|
// assert that Backup implements the ProgressPrinter interface
|
||||||
var _ ui.ProgressPrinter = &Backup{}
|
var _ ProgressPrinter = &JSONProgress{}
|
||||||
|
|
||||||
// NewBackup returns a new backup progress reporter.
|
// NewJSONProgress returns a new backup progress reporter.
|
||||||
func NewBackup(term *termstatus.Terminal, verbosity uint) *Backup {
|
func NewJSONProgress(term *termstatus.Terminal, verbosity uint) *JSONProgress {
|
||||||
return &Backup{
|
return &JSONProgress{
|
||||||
Message: ui.NewMessage(term, verbosity),
|
Message: ui.NewMessage(term, verbosity),
|
||||||
StdioWrapper: ui.NewStdioWrapper(term),
|
StdioWrapper: ui.NewStdioWrapper(term),
|
||||||
term: term,
|
term: term,
|
||||||
@ -44,16 +44,16 @@ func toJSONString(status interface{}) string {
|
|||||||
return buf.String()
|
return buf.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Backup) print(status interface{}) {
|
func (b *JSONProgress) print(status interface{}) {
|
||||||
b.term.Print(toJSONString(status))
|
b.term.Print(toJSONString(status))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Backup) error(status interface{}) {
|
func (b *JSONProgress) error(status interface{}) {
|
||||||
b.term.Error(toJSONString(status))
|
b.term.Error(toJSONString(status))
|
||||||
}
|
}
|
||||||
|
|
||||||
// update updates the status lines.
|
// Update updates the status lines.
|
||||||
func (b *Backup) Update(total, processed ui.Counter, errors uint, currentFiles map[string]struct{}, start time.Time, secs uint64) {
|
func (b *JSONProgress) Update(total, processed Counter, errors uint, currentFiles map[string]struct{}, start time.Time, secs uint64) {
|
||||||
status := statusUpdate{
|
status := statusUpdate{
|
||||||
MessageType: "status",
|
MessageType: "status",
|
||||||
SecondsElapsed: uint64(time.Since(start) / time.Second),
|
SecondsElapsed: uint64(time.Since(start) / time.Second),
|
||||||
@ -79,7 +79,7 @@ func (b *Backup) Update(total, processed ui.Counter, errors uint, currentFiles m
|
|||||||
|
|
||||||
// ScannerError is the error callback function for the scanner, it prints the
|
// ScannerError is the error callback function for the scanner, it prints the
|
||||||
// error in verbose mode and returns nil.
|
// error in verbose mode and returns nil.
|
||||||
func (b *Backup) ScannerError(item string, fi os.FileInfo, err error) error {
|
func (b *JSONProgress) ScannerError(item string, fi os.FileInfo, err error) error {
|
||||||
b.error(errorUpdate{
|
b.error(errorUpdate{
|
||||||
MessageType: "error",
|
MessageType: "error",
|
||||||
Error: err,
|
Error: err,
|
||||||
@ -90,7 +90,7 @@ func (b *Backup) ScannerError(item string, fi os.FileInfo, err error) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Error is the error callback function for the archiver, it prints the error and returns nil.
|
// Error is the error callback function for the archiver, it prints the error and returns nil.
|
||||||
func (b *Backup) Error(item string, fi os.FileInfo, err error) error {
|
func (b *JSONProgress) Error(item string, fi os.FileInfo, err error) error {
|
||||||
b.error(errorUpdate{
|
b.error(errorUpdate{
|
||||||
MessageType: "error",
|
MessageType: "error",
|
||||||
Error: err,
|
Error: err,
|
||||||
@ -102,7 +102,7 @@ func (b *Backup) Error(item string, fi os.FileInfo, err error) error {
|
|||||||
|
|
||||||
// CompleteItem is the status callback function for the archiver when a
|
// CompleteItem is the status callback function for the archiver when a
|
||||||
// file/dir has been saved successfully.
|
// file/dir has been saved successfully.
|
||||||
func (b *Backup) CompleteItem(messageType, item string, previous, current *restic.Node, s archiver.ItemStats, d time.Duration) {
|
func (b *JSONProgress) CompleteItem(messageType, item string, previous, current *restic.Node, s archiver.ItemStats, d time.Duration) {
|
||||||
if b.v < 2 {
|
if b.v < 2 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -158,7 +158,7 @@ func (b *Backup) CompleteItem(messageType, item string, previous, current *resti
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ReportTotal sets the total stats up to now
|
// ReportTotal sets the total stats up to now
|
||||||
func (b *Backup) ReportTotal(item string, start time.Time, s archiver.ScanStats) {
|
func (b *JSONProgress) ReportTotal(item string, start time.Time, s archiver.ScanStats) {
|
||||||
if b.v >= 2 {
|
if b.v >= 2 {
|
||||||
b.print(verboseUpdate{
|
b.print(verboseUpdate{
|
||||||
MessageType: "status",
|
MessageType: "status",
|
||||||
@ -171,7 +171,7 @@ func (b *Backup) ReportTotal(item string, start time.Time, s archiver.ScanStats)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Finish prints the finishing messages.
|
// Finish prints the finishing messages.
|
||||||
func (b *Backup) Finish(snapshotID restic.ID, start time.Time, summary *ui.Summary, dryRun bool) {
|
func (b *JSONProgress) Finish(snapshotID restic.ID, start time.Time, summary *Summary, dryRun bool) {
|
||||||
b.print(summaryOutput{
|
b.print(summaryOutput{
|
||||||
MessageType: "summary",
|
MessageType: "summary",
|
||||||
FilesNew: summary.Files.New,
|
FilesNew: summary.Files.New,
|
||||||
@ -192,7 +192,7 @@ func (b *Backup) Finish(snapshotID restic.ID, start time.Time, summary *ui.Summa
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Reset no-op
|
// Reset no-op
|
||||||
func (b *Backup) Reset() {
|
func (b *JSONProgress) Reset() {
|
||||||
}
|
}
|
||||||
|
|
||||||
type statusUpdate struct {
|
type statusUpdate struct {
|
@ -1,4 +1,4 @@
|
|||||||
package ui
|
package backup
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
@ -1,4 +1,4 @@
|
|||||||
package ui
|
package backup
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -8,31 +8,32 @@ import (
|
|||||||
|
|
||||||
"github.com/restic/restic/internal/archiver"
|
"github.com/restic/restic/internal/archiver"
|
||||||
"github.com/restic/restic/internal/restic"
|
"github.com/restic/restic/internal/restic"
|
||||||
|
"github.com/restic/restic/internal/ui"
|
||||||
"github.com/restic/restic/internal/ui/termstatus"
|
"github.com/restic/restic/internal/ui/termstatus"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Backup reports progress for the `backup` command.
|
// TextProgress reports progress for the `backup` command.
|
||||||
type Backup struct {
|
type TextProgress struct {
|
||||||
*Message
|
*ui.Message
|
||||||
*StdioWrapper
|
*ui.StdioWrapper
|
||||||
|
|
||||||
term *termstatus.Terminal
|
term *termstatus.Terminal
|
||||||
}
|
}
|
||||||
|
|
||||||
// assert that Backup implements the ProgressPrinter interface
|
// assert that Backup implements the ProgressPrinter interface
|
||||||
var _ ProgressPrinter = &Backup{}
|
var _ ProgressPrinter = &TextProgress{}
|
||||||
|
|
||||||
// NewBackup returns a new backup progress reporter.
|
// NewTextProgress returns a new backup progress reporter.
|
||||||
func NewBackup(term *termstatus.Terminal, verbosity uint) *Backup {
|
func NewTextProgress(term *termstatus.Terminal, verbosity uint) *TextProgress {
|
||||||
return &Backup{
|
return &TextProgress{
|
||||||
Message: NewMessage(term, verbosity),
|
Message: ui.NewMessage(term, verbosity),
|
||||||
StdioWrapper: NewStdioWrapper(term),
|
StdioWrapper: ui.NewStdioWrapper(term),
|
||||||
term: term,
|
term: term,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// update updates the status lines.
|
// Update updates the status lines.
|
||||||
func (b *Backup) Update(total, processed Counter, errors uint, currentFiles map[string]struct{}, start time.Time, secs uint64) {
|
func (b *TextProgress) Update(total, processed Counter, errors uint, currentFiles map[string]struct{}, start time.Time, secs uint64) {
|
||||||
var status string
|
var status string
|
||||||
if total.Files == 0 && total.Dirs == 0 {
|
if total.Files == 0 && total.Dirs == 0 {
|
||||||
// no total count available yet
|
// no total count available yet
|
||||||
@ -74,13 +75,13 @@ func (b *Backup) Update(total, processed Counter, errors uint, currentFiles map[
|
|||||||
|
|
||||||
// ScannerError is the error callback function for the scanner, it prints the
|
// ScannerError is the error callback function for the scanner, it prints the
|
||||||
// error in verbose mode and returns nil.
|
// error in verbose mode and returns nil.
|
||||||
func (b *Backup) ScannerError(item string, fi os.FileInfo, err error) error {
|
func (b *TextProgress) ScannerError(item string, fi os.FileInfo, err error) error {
|
||||||
b.V("scan: %v\n", err)
|
b.V("scan: %v\n", err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Error is the error callback function for the archiver, it prints the error and returns nil.
|
// Error is the error callback function for the archiver, it prints the error and returns nil.
|
||||||
func (b *Backup) Error(item string, fi os.FileInfo, err error) error {
|
func (b *TextProgress) Error(item string, fi os.FileInfo, err error) error {
|
||||||
b.E("error: %v\n", err)
|
b.E("error: %v\n", err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -134,7 +135,7 @@ func formatBytes(c uint64) string {
|
|||||||
|
|
||||||
// CompleteItem is the status callback function for the archiver when a
|
// CompleteItem is the status callback function for the archiver when a
|
||||||
// file/dir has been saved successfully.
|
// file/dir has been saved successfully.
|
||||||
func (b *Backup) CompleteItem(messageType, item string, previous, current *restic.Node, s archiver.ItemStats, d time.Duration) {
|
func (b *TextProgress) CompleteItem(messageType, item string, previous, current *restic.Node, s archiver.ItemStats, d time.Duration) {
|
||||||
switch messageType {
|
switch messageType {
|
||||||
case "dir new":
|
case "dir new":
|
||||||
b.VV("new %v, saved in %.3fs (%v added, %v metadata)", item, d.Seconds(), formatBytes(s.DataSize), formatBytes(s.TreeSize))
|
b.VV("new %v, saved in %.3fs (%v added, %v metadata)", item, d.Seconds(), formatBytes(s.DataSize), formatBytes(s.TreeSize))
|
||||||
@ -152,7 +153,7 @@ func (b *Backup) CompleteItem(messageType, item string, previous, current *resti
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ReportTotal sets the total stats up to now
|
// ReportTotal sets the total stats up to now
|
||||||
func (b *Backup) ReportTotal(item string, start time.Time, s archiver.ScanStats) {
|
func (b *TextProgress) ReportTotal(item string, start time.Time, s archiver.ScanStats) {
|
||||||
b.V("scan finished in %.3fs: %v files, %s",
|
b.V("scan finished in %.3fs: %v files, %s",
|
||||||
time.Since(start).Seconds(),
|
time.Since(start).Seconds(),
|
||||||
s.Files, formatBytes(s.Bytes),
|
s.Files, formatBytes(s.Bytes),
|
||||||
@ -160,14 +161,14 @@ func (b *Backup) ReportTotal(item string, start time.Time, s archiver.ScanStats)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Reset status
|
// Reset status
|
||||||
func (b *Backup) Reset() {
|
func (b *TextProgress) Reset() {
|
||||||
if b.term.CanUpdateStatus() {
|
if b.term.CanUpdateStatus() {
|
||||||
b.term.SetStatus([]string{""})
|
b.term.SetStatus([]string{""})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Finish prints the finishing messages.
|
// Finish prints the finishing messages.
|
||||||
func (b *Backup) Finish(snapshotID restic.ID, start time.Time, summary *Summary, dryRun bool) {
|
func (b *TextProgress) Finish(snapshotID restic.ID, start time.Time, summary *Summary, dryRun bool) {
|
||||||
b.P("\n")
|
b.P("\n")
|
||||||
b.P("Files: %5d new, %5d changed, %5d unmodified\n", summary.Files.New, summary.Files.Changed, summary.Files.Unchanged)
|
b.P("Files: %5d new, %5d changed, %5d unmodified\n", summary.Files.New, summary.Files.Changed, summary.Files.Unchanged)
|
||||||
b.P("Dirs: %5d new, %5d changed, %5d unmodified\n", summary.Dirs.New, summary.Dirs.Changed, summary.Dirs.Unchanged)
|
b.P("Dirs: %5d new, %5d changed, %5d unmodified\n", summary.Dirs.New, summary.Dirs.Changed, summary.Dirs.Unchanged)
|
Loading…
Reference in New Issue
Block a user