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  }