github.com/mckael/restic@v0.8.3/cmd/restic/main.go (about) 1 package main 2 3 import ( 4 "bufio" 5 "bytes" 6 "fmt" 7 "log" 8 "os" 9 "runtime" 10 11 "github.com/restic/restic/internal/debug" 12 "github.com/restic/restic/internal/options" 13 "github.com/restic/restic/internal/restic" 14 15 "github.com/spf13/cobra" 16 17 "github.com/restic/restic/internal/errors" 18 ) 19 20 // cmdRoot is the base command when no other command has been specified. 21 var cmdRoot = &cobra.Command{ 22 Use: "restic", 23 Short: "Backup and restore files", 24 Long: ` 25 restic is a backup program which allows saving multiple revisions of files and 26 directories in an encrypted repository stored on different backends. 27 `, 28 SilenceErrors: true, 29 SilenceUsage: true, 30 DisableAutoGenTag: true, 31 32 PersistentPreRunE: func(*cobra.Command, []string) error { 33 // parse extended options 34 opts, err := options.Parse(globalOptions.Options) 35 if err != nil { 36 return err 37 } 38 globalOptions.extended = opts 39 40 pwd, err := resolvePassword(globalOptions, "RESTIC_PASSWORD") 41 if err != nil { 42 fmt.Fprintf(os.Stderr, "Resolving password failed: %v\n", err) 43 Exit(1) 44 } 45 globalOptions.password = pwd 46 47 // run the debug functions for all subcommands (if build tag "debug" is 48 // enabled) 49 if err := runDebug(); err != nil { 50 return err 51 } 52 53 return nil 54 }, 55 } 56 57 var logBuffer = bytes.NewBuffer(nil) 58 59 func init() { 60 // install custom global logger into a buffer, if an error occurs 61 // we can show the logs 62 log.SetOutput(logBuffer) 63 } 64 65 func main() { 66 debug.Log("main %#v", os.Args) 67 debug.Log("restic %s, compiled with %v on %v/%v", 68 version, runtime.Version(), runtime.GOOS, runtime.GOARCH) 69 err := cmdRoot.Execute() 70 71 switch { 72 case restic.IsAlreadyLocked(errors.Cause(err)): 73 fmt.Fprintf(os.Stderr, "%v\nthe `unlock` command can be used to remove stale locks\n", err) 74 case errors.IsFatal(errors.Cause(err)): 75 fmt.Fprintf(os.Stderr, "%v\n", err) 76 case err != nil: 77 fmt.Fprintf(os.Stderr, "%+v\n", err) 78 79 if logBuffer.Len() > 0 { 80 fmt.Fprintf(os.Stderr, "also, the following messages were logged by a library:\n") 81 sc := bufio.NewScanner(logBuffer) 82 for sc.Scan() { 83 fmt.Fprintln(os.Stderr, sc.Text()) 84 } 85 } 86 } 87 88 var exitCode int 89 if err != nil { 90 exitCode = 1 91 } 92 93 Exit(exitCode) 94 }