| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110 | package cliimport (	"fmt"	"io"	"os"	"strings")// OsExiter is the function used when the app exits. If not set defaults to os.Exit.var OsExiter = os.Exit// ErrWriter is used to write errors to the user. This can be anything// implementing the io.Writer interface and defaults to os.Stderr.var ErrWriter io.Writer = os.Stderr// MultiError is an error that wraps multiple errors.type MultiError struct {	Errors []error}// NewMultiError creates a new MultiError. Pass in one or more errors.func NewMultiError(err ...error) MultiError {	return MultiError{Errors: err}}// Error implements the error interface.func (m MultiError) Error() string {	errs := make([]string, len(m.Errors))	for i, err := range m.Errors {		errs[i] = err.Error()	}	return strings.Join(errs, "\n")}type ErrorFormatter interface {	Format(s fmt.State, verb rune)}// ExitCoder is the interface checked by `App` and `Command` for a custom exit// codetype ExitCoder interface {	error	ExitCode() int}// ExitError fulfills both the builtin `error` interface and `ExitCoder`type ExitError struct {	exitCode int	message  interface{}}// NewExitError makes a new *ExitErrorfunc NewExitError(message interface{}, exitCode int) *ExitError {	return &ExitError{		exitCode: exitCode,		message:  message,	}}// Error returns the string message, fulfilling the interface required by// `error`func (ee *ExitError) Error() string {	return fmt.Sprintf("%v", ee.message)}// ExitCode returns the exit code, fulfilling the interface required by// `ExitCoder`func (ee *ExitError) ExitCode() int {	return ee.exitCode}// HandleExitCoder checks if the error fulfills the ExitCoder interface, and if// so prints the error to stderr (if it is non-empty) and calls OsExiter with the// given exit code.  If the given error is a MultiError, then this func is// called on all members of the Errors slice.func HandleExitCoder(err error) {	if err == nil {		return	}	if exitErr, ok := err.(ExitCoder); ok {		if err.Error() != "" {			if _, ok := exitErr.(ErrorFormatter); ok {				fmt.Fprintf(ErrWriter, "%+v\n", err)			} else {				fmt.Fprintln(ErrWriter, err)			}		}		OsExiter(exitErr.ExitCode())		return	}	if multiErr, ok := err.(MultiError); ok {		for _, merr := range multiErr.Errors {			HandleExitCoder(merr)		}		return	}	if err.Error() != "" {		if _, ok := err.(ErrorFormatter); ok {			fmt.Fprintf(ErrWriter, "%+v\n", err)		} else {			fmt.Fprintln(ErrWriter, err)		}	}	OsExiter(1)}
 |