fix incorrent exit code
Signed-off-by: yxxhero <aiopsclub@163.com>
This commit is contained in:
		
							parent
							
								
									98ca036d99
								
							
						
					
					
						commit
						76bf9952b9
					
				| 
						 | 
					@ -6,12 +6,12 @@ import (
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/spf13/cobra"
 | 
						"github.com/spf13/cobra"
 | 
				
			||||||
	"github.com/spf13/pflag"
 | 
						"github.com/spf13/pflag"
 | 
				
			||||||
	"github.com/urfave/cli"
 | 
					 | 
				
			||||||
	"go.uber.org/zap"
 | 
						"go.uber.org/zap"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/helmfile/helmfile/pkg/app"
 | 
						"github.com/helmfile/helmfile/pkg/app"
 | 
				
			||||||
	"github.com/helmfile/helmfile/pkg/app/version"
 | 
						"github.com/helmfile/helmfile/pkg/app/version"
 | 
				
			||||||
	"github.com/helmfile/helmfile/pkg/config"
 | 
						"github.com/helmfile/helmfile/pkg/config"
 | 
				
			||||||
 | 
						"github.com/helmfile/helmfile/pkg/errors"
 | 
				
			||||||
	"github.com/helmfile/helmfile/pkg/helmexec"
 | 
						"github.com/helmfile/helmfile/pkg/helmexec"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -26,11 +26,11 @@ func toCLIError(g *config.GlobalImpl, err error) error {
 | 
				
			||||||
			if g.AllowNoMatchingRelease {
 | 
								if g.AllowNoMatchingRelease {
 | 
				
			||||||
				noMatchingExitCode = 0
 | 
									noMatchingExitCode = 0
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			return cli.NewExitError(e.Error(), noMatchingExitCode)
 | 
								return errors.NewExitError(e.Error(), noMatchingExitCode)
 | 
				
			||||||
		case *app.MultiError:
 | 
							case *app.MultiError:
 | 
				
			||||||
			return cli.NewExitError(e.Error(), 1)
 | 
								return errors.NewExitError(e.Error(), 1)
 | 
				
			||||||
		case *app.Error:
 | 
							case *app.Error:
 | 
				
			||||||
			return cli.NewExitError(e.Error(), e.Code())
 | 
								return errors.NewExitError(e.Error(), e.Code())
 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
			panic(fmt.Errorf("BUG: please file an github issue for this unhandled error: %T: %v", e, e))
 | 
								panic(fmt.Errorf("BUG: please file an github issue for this unhandled error: %T: %v", e, e))
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -47,6 +47,7 @@ func NewRootCmd(globalConfig *config.GlobalOptions, args []string) (*cobra.Comma
 | 
				
			||||||
		Args:          cobra.MinimumNArgs(1),
 | 
							Args:          cobra.MinimumNArgs(1),
 | 
				
			||||||
		Version:       version.GetVersion(),
 | 
							Version:       version.GetVersion(),
 | 
				
			||||||
		SilenceUsage:  true,
 | 
							SilenceUsage:  true,
 | 
				
			||||||
 | 
							SilenceErrors: true,
 | 
				
			||||||
		PersistentPreRunE: func(c *cobra.Command, args []string) error {
 | 
							PersistentPreRunE: func(c *cobra.Command, args []string) error {
 | 
				
			||||||
			// Valid levels:
 | 
								// Valid levels:
 | 
				
			||||||
			// https://github.com/uber-go/zap/blob/7e7e266a8dbce911a49554b945538c5b950196b8/zapcore/level.go#L126
 | 
								// https://github.com/uber-go/zap/blob/7e7e266a8dbce911a49554b945538c5b950196b8/zapcore/level.go#L126
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										3
									
								
								go.mod
								
								
								
								
							
							
						
						
									
										3
									
								
								go.mod
								
								
								
								
							| 
						 | 
					@ -24,7 +24,6 @@ require (
 | 
				
			||||||
	github.com/spf13/pflag v1.0.5
 | 
						github.com/spf13/pflag v1.0.5
 | 
				
			||||||
	github.com/stretchr/testify v1.8.0
 | 
						github.com/stretchr/testify v1.8.0
 | 
				
			||||||
	github.com/tatsushid/go-prettytable v0.0.0-20141013043238-ed2d14c29939
 | 
						github.com/tatsushid/go-prettytable v0.0.0-20141013043238-ed2d14c29939
 | 
				
			||||||
	github.com/urfave/cli v1.22.10
 | 
					 | 
				
			||||||
	github.com/variantdev/chartify v0.10.2
 | 
						github.com/variantdev/chartify v0.10.2
 | 
				
			||||||
	github.com/variantdev/dag v1.1.0
 | 
						github.com/variantdev/dag v1.1.0
 | 
				
			||||||
	github.com/variantdev/vals v0.18.0
 | 
						github.com/variantdev/vals v0.18.0
 | 
				
			||||||
| 
						 | 
					@ -62,7 +61,6 @@ require (
 | 
				
			||||||
	github.com/aws/aws-sdk-go v1.40.28 // indirect
 | 
						github.com/aws/aws-sdk-go v1.40.28 // indirect
 | 
				
			||||||
	github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect
 | 
						github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect
 | 
				
			||||||
	github.com/blang/semver v3.5.1+incompatible // indirect
 | 
						github.com/blang/semver v3.5.1+incompatible // indirect
 | 
				
			||||||
	github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
 | 
					 | 
				
			||||||
	github.com/dimchansky/utfbom v1.1.1 // indirect
 | 
						github.com/dimchansky/utfbom v1.1.1 // indirect
 | 
				
			||||||
	github.com/fatih/color v1.13.0 // indirect
 | 
						github.com/fatih/color v1.13.0 // indirect
 | 
				
			||||||
	github.com/fujiwara/tfstate-lookup v0.4.4 // indirect
 | 
						github.com/fujiwara/tfstate-lookup v0.4.4 // indirect
 | 
				
			||||||
| 
						 | 
					@ -107,7 +105,6 @@ require (
 | 
				
			||||||
	github.com/pbnjay/strptime v0.0.0-20140226051138-5c05b0d668c9 // indirect
 | 
						github.com/pbnjay/strptime v0.0.0-20140226051138-5c05b0d668c9 // indirect
 | 
				
			||||||
	github.com/pkg/errors v0.9.1 // indirect
 | 
						github.com/pkg/errors v0.9.1 // indirect
 | 
				
			||||||
	github.com/pmezard/go-difflib v1.0.0 // indirect
 | 
						github.com/pmezard/go-difflib v1.0.0 // indirect
 | 
				
			||||||
	github.com/russross/blackfriday/v2 v2.1.0 // indirect
 | 
					 | 
				
			||||||
	github.com/ryanuber/go-glob v1.0.0 // indirect
 | 
						github.com/ryanuber/go-glob v1.0.0 // indirect
 | 
				
			||||||
	github.com/sergi/go-diff v1.1.0 // indirect
 | 
						github.com/sergi/go-diff v1.1.0 // indirect
 | 
				
			||||||
	github.com/shopspring/decimal v1.2.0 // indirect
 | 
						github.com/shopspring/decimal v1.2.0 // indirect
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										4
									
								
								go.sum
								
								
								
								
							
							
						
						
									
										4
									
								
								go.sum
								
								
								
								
							| 
						 | 
					@ -394,7 +394,6 @@ github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfc
 | 
				
			||||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
 | 
					github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
 | 
				
			||||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
 | 
					github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
 | 
				
			||||||
github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
 | 
					github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
 | 
				
			||||||
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
 | 
					 | 
				
			||||||
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
 | 
					github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
 | 
				
			||||||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
 | 
					github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
 | 
				
			||||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
 | 
					github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
 | 
				
			||||||
| 
						 | 
					@ -1144,7 +1143,6 @@ github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTE
 | 
				
			||||||
github.com/rubenv/sql-migrate v0.0.0-20210614095031-55d5740dbbcc/go.mod h1:HFLT6i9iR4QBOF5rdCyjddC9t59ArqWJV2xx+jwcCMo=
 | 
					github.com/rubenv/sql-migrate v0.0.0-20210614095031-55d5740dbbcc/go.mod h1:HFLT6i9iR4QBOF5rdCyjddC9t59ArqWJV2xx+jwcCMo=
 | 
				
			||||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
 | 
					github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
 | 
				
			||||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
 | 
					github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
 | 
				
			||||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
 | 
					 | 
				
			||||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
 | 
					github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
 | 
				
			||||||
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
 | 
					github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
 | 
				
			||||||
github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
 | 
					github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
 | 
				
			||||||
| 
						 | 
					@ -1245,8 +1243,6 @@ github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/
 | 
				
			||||||
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
 | 
					github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
 | 
				
			||||||
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
 | 
					github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
 | 
				
			||||||
github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
 | 
					github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
 | 
				
			||||||
github.com/urfave/cli v1.22.10 h1:p8Fspmz3iTctJstry1PYS3HVdllxnEzTEsgIgtxTrCk=
 | 
					 | 
				
			||||||
github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
 | 
					 | 
				
			||||||
github.com/variantdev/chartify v0.10.2 h1:CAMlSE4kBl8ft/Xl4ob+eyFZ2KV5evkiMEI43M4CaKs=
 | 
					github.com/variantdev/chartify v0.10.2 h1:CAMlSE4kBl8ft/Xl4ob+eyFZ2KV5evkiMEI43M4CaKs=
 | 
				
			||||||
github.com/variantdev/chartify v0.10.2/go.mod h1:A0nQmb+ihiBJrrbgofs1t7QVeit+/llT0vJhvkj7U0Q=
 | 
					github.com/variantdev/chartify v0.10.2/go.mod h1:A0nQmb+ihiBJrrbgofs1t7QVeit+/llT0vJhvkj7U0Q=
 | 
				
			||||||
github.com/variantdev/dag v1.1.0 h1:xodYlSng33KWGvIGMpKUyLcIZRXKiNUx612mZJqYrDg=
 | 
					github.com/variantdev/dag v1.1.0 h1:xodYlSng33KWGvIGMpKUyLcIZRXKiNUx612mZJqYrDg=
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										17
									
								
								main.go
								
								
								
								
							
							
						
						
									
										17
									
								
								main.go
								
								
								
								
							| 
						 | 
					@ -1,28 +1,19 @@
 | 
				
			||||||
package main
 | 
					package main
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"os"
 | 
						"os"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/urfave/cli"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	"github.com/helmfile/helmfile/cmd"
 | 
						"github.com/helmfile/helmfile/cmd"
 | 
				
			||||||
	"github.com/helmfile/helmfile/pkg/config"
 | 
						"github.com/helmfile/helmfile/pkg/config"
 | 
				
			||||||
 | 
						"github.com/helmfile/helmfile/pkg/errors"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func warning(format string, v ...interface{}) {
 | 
					 | 
				
			||||||
	format = fmt.Sprintf("WARNING: %s\n", format)
 | 
					 | 
				
			||||||
	fmt.Fprintf(os.Stderr, format, v...)
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func main() {
 | 
					func main() {
 | 
				
			||||||
	globalConfig := new(config.GlobalOptions)
 | 
						globalConfig := new(config.GlobalOptions)
 | 
				
			||||||
	rootCmd, err := cmd.NewRootCmd(globalConfig, os.Args[1:])
 | 
						rootCmd, err := cmd.NewRootCmd(globalConfig, os.Args[1:])
 | 
				
			||||||
	if err != nil {
 | 
						errors.HandleExitCoder(err)
 | 
				
			||||||
		warning("%+v", err)
 | 
					
 | 
				
			||||||
		os.Exit(1)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if err := rootCmd.Execute(); err != nil {
 | 
						if err := rootCmd.Execute(); err != nil {
 | 
				
			||||||
		cli.HandleExitCoder(err)
 | 
							errors.HandleExitCoder(err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,97 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					* MIT License
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					* Copyright (c) 2022 urfave/cli maintainers
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					* Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
				
			||||||
 | 
					* of this software and associated documentation files (the "Software"), to deal
 | 
				
			||||||
 | 
					* in the Software without restriction, including without limitation the rights
 | 
				
			||||||
 | 
					* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
				
			||||||
 | 
					* copies of the Software, and to permit persons to whom the Software is
 | 
				
			||||||
 | 
					* furnished to do so, subject to the following conditions:
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					* The above copyright notice and this permission notice shall be included in all
 | 
				
			||||||
 | 
					* copies or substantial portions of the Software.
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
				
			||||||
 | 
					* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
				
			||||||
 | 
					* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
				
			||||||
 | 
					* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
				
			||||||
 | 
					* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
				
			||||||
 | 
					* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
				
			||||||
 | 
					* SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package errors
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"io"
 | 
				
			||||||
 | 
						"os"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type ErrorFormatter interface {
 | 
				
			||||||
 | 
						Format(s fmt.State, verb rune)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ExitCoder is the interface checked by `App` and `Command` for a custom exit
 | 
				
			||||||
 | 
					// code
 | 
				
			||||||
 | 
					type 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 *ExitError
 | 
				
			||||||
 | 
					func 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 and calls OsExiter with the last exit code.
 | 
				
			||||||
 | 
					func HandleExitCoder(err error) {
 | 
				
			||||||
 | 
						if err == nil {
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if exitErr, ok := err.(ExitCoder); ok {
 | 
				
			||||||
 | 
							if err.Error() != "" {
 | 
				
			||||||
 | 
								fmt.Fprintln(ErrWriter, err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							OsExiter(exitErr.ExitCode())
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// unknown error exit with code 3
 | 
				
			||||||
 | 
						fmt.Fprintln(ErrWriter, err)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						OsExiter(3)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,87 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					* MIT License
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					* Copyright (c) 2022 urfave/cli maintainers
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					* Permission is hereby granted, free of charge, to any person obtaining a copy
 | 
				
			||||||
 | 
					* of this software and associated documentation files (the "Software"), to deal
 | 
				
			||||||
 | 
					* in the Software without restriction, including without limitation the rights
 | 
				
			||||||
 | 
					* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | 
				
			||||||
 | 
					* copies of the Software, and to permit persons to whom the Software is
 | 
				
			||||||
 | 
					* furnished to do so, subject to the following conditions:
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					* The above copyright notice and this permission notice shall be included in all
 | 
				
			||||||
 | 
					* copies or substantial portions of the Software.
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
 | 
					* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | 
				
			||||||
 | 
					* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | 
				
			||||||
 | 
					* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | 
				
			||||||
 | 
					* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | 
				
			||||||
 | 
					* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | 
				
			||||||
 | 
					* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 | 
				
			||||||
 | 
					* SOFTWARE.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					package errors
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"os"
 | 
				
			||||||
 | 
						"reflect"
 | 
				
			||||||
 | 
						"runtime"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
						"testing"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/stretchr/testify/require"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var (
 | 
				
			||||||
 | 
						wd, _        = os.Getwd()
 | 
				
			||||||
 | 
						lastExitCode = 0
 | 
				
			||||||
 | 
						fakeOsExiter = func(rc int) {
 | 
				
			||||||
 | 
							lastExitCode = rc
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func expect(t *testing.T, a interface{}, b interface{}) {
 | 
				
			||||||
 | 
						_, fn, line, _ := runtime.Caller(1)
 | 
				
			||||||
 | 
						fn = strings.Replace(fn, wd+"/", "", -1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						require.Equalf(t, a, b, "(%s:%d) Expected %v (type %v) - Got %v (type %v)", fn, line, b, reflect.TypeOf(b), a, reflect.TypeOf(a))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestHandleExitCoder_nil(t *testing.T) {
 | 
				
			||||||
 | 
						exitCode := 0
 | 
				
			||||||
 | 
						called := false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						OsExiter = func(rc int) {
 | 
				
			||||||
 | 
							if !called {
 | 
				
			||||||
 | 
								exitCode = rc
 | 
				
			||||||
 | 
								called = true
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						defer func() { OsExiter = fakeOsExiter }()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						HandleExitCoder(nil)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						expect(t, exitCode, 0)
 | 
				
			||||||
 | 
						expect(t, called, false)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestHandleExitCoder_ExitCoder(t *testing.T) {
 | 
				
			||||||
 | 
						exitCode := 0
 | 
				
			||||||
 | 
						called := false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						OsExiter = func(rc int) {
 | 
				
			||||||
 | 
							if !called {
 | 
				
			||||||
 | 
								exitCode = rc
 | 
				
			||||||
 | 
								called = true
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						defer func() { OsExiter = fakeOsExiter }()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						HandleExitCoder(NewExitError("galactic perimeter breach", 9))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						expect(t, exitCode, 9)
 | 
				
			||||||
 | 
						expect(t, called, true)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
		Reference in New Issue