backup/restore: extract termstatus initialization

This commit is contained in:
Michael Eischer 2024-01-20 18:10:11 +01:00
parent cb50832d50
commit d26d2d41f8
3 changed files with 48 additions and 53 deletions

View file

@ -12,7 +12,6 @@ import (
"runtime" "runtime"
"strconv" "strconv"
"strings" "strings"
"sync"
"time" "time"
"github.com/spf13/cobra" "github.com/spf13/cobra"
@ -25,7 +24,6 @@ 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/backup"
"github.com/restic/restic/internal/ui/termstatus" "github.com/restic/restic/internal/ui/termstatus"
) )
@ -56,31 +54,9 @@ Exit status is 3 if some source data could not be read (incomplete snapshot crea
}, },
DisableAutoGenTag: true, DisableAutoGenTag: true,
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
ctx := cmd.Context() term, cancel := setupTermstatus(cmd.Context())
var wg sync.WaitGroup defer cancel()
cancelCtx, cancel := context.WithCancel(ctx) return runBackup(cmd.Context(), backupOptions, globalOptions, term, args)
defer func() {
// shutdown termstatus
cancel()
wg.Wait()
}()
term := termstatus.New(globalOptions.stdout, globalOptions.stderr, globalOptions.Quiet)
wg.Add(1)
go func() {
defer wg.Done()
term.Run(cancelCtx)
}()
// use the terminal for stdout/stderr
prevStdout, prevStderr := globalOptions.stdout, globalOptions.stderr
defer func() {
globalOptions.stdout, globalOptions.stderr = prevStdout, prevStderr
}()
stdioWrapper := ui.NewStdioWrapper(term)
globalOptions.stdout, globalOptions.stderr = stdioWrapper.Stdout(), stdioWrapper.Stderr()
return runBackup(ctx, backupOptions, globalOptions, term, args)
}, },
} }

View file

@ -3,7 +3,6 @@ package main
import ( import (
"context" "context"
"strings" "strings"
"sync"
"time" "time"
"github.com/restic/restic/internal/debug" "github.com/restic/restic/internal/debug"
@ -38,31 +37,9 @@ Exit status is 0 if the command was successful, and non-zero if there was any er
`, `,
DisableAutoGenTag: true, DisableAutoGenTag: true,
RunE: func(cmd *cobra.Command, args []string) error { RunE: func(cmd *cobra.Command, args []string) error {
ctx := cmd.Context() term, cancel := setupTermstatus(cmd.Context())
var wg sync.WaitGroup defer cancel()
cancelCtx, cancel := context.WithCancel(ctx) return runRestore(cmd.Context(), restoreOptions, globalOptions, term, args)
defer func() {
// shutdown termstatus
cancel()
wg.Wait()
}()
term := termstatus.New(globalOptions.stdout, globalOptions.stderr, globalOptions.Quiet)
wg.Add(1)
go func() {
defer wg.Done()
term.Run(cancelCtx)
}()
// allow usage of warnf / verbosef
prevStdout, prevStderr := globalOptions.stdout, globalOptions.stderr
defer func() {
globalOptions.stdout, globalOptions.stderr = prevStdout, prevStderr
}()
stdioWrapper := ui.NewStdioWrapper(term)
globalOptions.stdout, globalOptions.stderr = stdioWrapper.Stdout(), stdioWrapper.Stderr()
return runRestore(ctx, restoreOptions, globalOptions, term, args)
}, },
} }

42
cmd/restic/termstatus.go Normal file
View file

@ -0,0 +1,42 @@
package main
import (
"context"
"sync"
"github.com/restic/restic/internal/ui"
"github.com/restic/restic/internal/ui/termstatus"
)
// setupTermstatus creates a new termstatus and reroutes globalOptions.{stdout,stderr} to it
// The returned function must be called to shut down the termstatus,
//
// Expected usage:
// ```
// term, cancel := setupTermstatus(ctx)
// defer cancel()
// // do stuff
// ```
func setupTermstatus(ctx context.Context) (*termstatus.Terminal, func()) {
var wg sync.WaitGroup
cancelCtx, cancel := context.WithCancel(ctx)
term := termstatus.New(globalOptions.stdout, globalOptions.stderr, globalOptions.Quiet)
wg.Add(1)
go func() {
defer wg.Done()
term.Run(cancelCtx)
}()
// use the termstatus for stdout/stderr
prevStdout, prevStderr := globalOptions.stdout, globalOptions.stderr
stdioWrapper := ui.NewStdioWrapper(term)
globalOptions.stdout, globalOptions.stderr = stdioWrapper.Stdout(), stdioWrapper.Stderr()
return term, func() {
// shutdown termstatus
globalOptions.stdout, globalOptions.stderr = prevStdout, prevStderr
cancel()
wg.Wait()
}
}