From 5fc7d0a3e67586a2acd649588ebb6719d0b920c5 Mon Sep 17 00:00:00 2001 From: Ignasi Barrera Date: Tue, 13 Feb 2024 23:22:09 +0100 Subject: [PATCH 1/3] Remove multierror dependency --- example_group_test.go | 13 +++++-------- go.mod | 3 --- go.sum | 4 ---- group.go | 24 ++++++++---------------- group_test.go | 8 +------- 5 files changed, 14 insertions(+), 38 deletions(-) diff --git a/example_group_test.go b/example_group_test.go index 028bcfb..c320b4e 100644 --- a/example_group_test.go +++ b/example_group_test.go @@ -20,8 +20,6 @@ import ( "os" "github.com/spf13/pflag" - "github.com/tetratelabs/multierror" - "github.com/tetratelabs/run" "github.com/tetratelabs/run/pkg/signal" ) @@ -75,18 +73,17 @@ func (p *PersonService) FlagSet() *pflag.FlagSet { // Validate implements run.Config and thus its configuration and flag handling // is automatically registered when adding the service to Group. func (p PersonService) Validate() error { - var err error + var errs []error if p.name == "" { - err = multierror.Append(err, errors.New("invalid name provided")) + errs = append(errs, errors.New("invalid name provided")) } if p.age < 18 { - err = multierror.Append(err, errors.New("invalid age provided, we don't serve minors")) + errs = append(errs, errors.New("invalid age provided, we don't serve minors")) } if p.age > 110 { - err = multierror.Append(err, errors.New("faking it? or life expectancy assumptions surpassed by future healthcare system")) + errs = append(errs, errors.New("faking it? or life expectancy assumptions surpassed by future healthcare system")) } - - return err + return errors.Join(errs...) } // PreRun implements run.PreRunner and thus this method is run at the pre-run diff --git a/go.mod b/go.mod index c68d2ef..f54c286 100644 --- a/go.mod +++ b/go.mod @@ -5,8 +5,5 @@ go 1.17 require ( github.com/logrusorgru/aurora v2.0.3+incompatible github.com/spf13/pflag v1.0.5 - github.com/tetratelabs/multierror v1.1.0 github.com/tetratelabs/telemetry v0.7.1 ) - -require github.com/hashicorp/errwrap v1.0.0 // indirect diff --git a/go.sum b/go.sum index f8fc36f..42529bf 100644 --- a/go.sum +++ b/go.sum @@ -1,10 +1,6 @@ -github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= -github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczGlG91VSDkswnjF5A8= github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/tetratelabs/multierror v1.1.0 h1:cKmV/Pbf42K5wp8glxa2YIausbxIraPN8fzru9Pn1Cg= -github.com/tetratelabs/multierror v1.1.0/go.mod h1:kH3SzI/z+FwEbV9bxQDx4GiIgE2djuyb8wiB2DaUBnY= github.com/tetratelabs/telemetry v0.7.1 h1:IiDiiZgShKlHjPFgCAE6ZD4URH3r8yj7SDAEN/ImHYA= github.com/tetratelabs/telemetry v0.7.1/go.mod h1:jDUcf1A2u4F5V1io5RdipM/bKz/hFCsx/RAgGopC37s= diff --git a/group.go b/group.go index 4688992..84fb43f 100644 --- a/group.go +++ b/group.go @@ -29,7 +29,6 @@ import ( color "github.com/logrusorgru/aurora" "github.com/spf13/pflag" - "github.com/tetratelabs/multierror" "github.com/tetratelabs/telemetry" "github.com/tetratelabs/run/pkg/log" @@ -40,22 +39,16 @@ import ( // name in HelpText strings. const BinaryName = "{{.Name}}" -// Error allows for creating constant errors instead of sentinel ones. -type Error string - -// Error implements error. -func (e Error) Error() string { return string(e) } - // ErrBailEarlyRequest is returned when a call to RunConfig was successful but // signals that the application should exit in success immediately. // It is typically returned on --version and --help requests that have been // served. It can and should be used for custom config phase situations where // the job of the application is done. -const ErrBailEarlyRequest Error = "exit request from flag handler" +var ErrBailEarlyRequest = errors.New("exit request from flag handler") // ErrRequestedShutdown can be used by Service implementations to gracefully // request a shutdown of the application. Group will then exit without errors. -const ErrRequestedShutdown Error = "shutdown requested" +var ErrRequestedShutdown = errors.New("shutdown requested") // FlagSet holds a pflag.FlagSet as well as an exported Name variable for // allowing improved help usage information. @@ -339,9 +332,8 @@ func (g *Group) RunConfig(args ...string) (err error) { g.HelpText = strings.ReplaceAll(g.HelpText, BinaryName, os.Args[0]) defer func() { - if err != nil && err != ErrBailEarlyRequest { + if err != nil && !errors.Is(err, ErrBailEarlyRequest) { g.Logger.Error("unexpected exit", err) - err = multierror.SetFormatter(err, multierror.ListFormatFunc) } }() @@ -464,6 +456,7 @@ func (g *Group) RunConfig(args ...string) (err error) { } // Validate Config inputs + var errs []error for idx, cfg := range g.c { func(itemNr int, cfg Config) { // a Config might have been de-registered during Run @@ -482,14 +475,14 @@ func (g *Group) RunConfig(args ...string) (err error) { defer l.Debug("validate-exit", debugLogError(vErr)...) vErr = cfg.Validate() if vErr != nil { - err = multierror.Append(err, vErr) + errs = append(errs, vErr) } }(idx+1, cfg) } // exit on at least one Validate error - if err != nil { - return err + if len(errs) > 0 { + return fmt.Errorf("%d errors occured:\n%w", len(errs), errors.Join(errs...)) } // log binary name and version @@ -539,7 +532,7 @@ func (g *Group) Run(args ...string) (err error) { if !g.configured { // run config registration and flag parsing stages if err = g.RunConfig(args...); err != nil { - if err == ErrBailEarlyRequest { + if errors.Is(err, ErrBailEarlyRequest) { return nil } return err @@ -571,7 +564,6 @@ func (g *Group) Run(args ...string) (err error) { } // actual fatal error g.Logger.Error("unexpected exit", err) - err = multierror.SetFormatter(err, multierror.ListFormatFunc) }() // call our Initializer (again) diff --git a/group_test.go b/group_test.go index 2afc233..d96840a 100644 --- a/group_test.go +++ b/group_test.go @@ -22,8 +22,6 @@ import ( "testing" "time" - "github.com/tetratelabs/multierror" - "github.com/tetratelabs/run" "github.com/tetratelabs/run/pkg/test" ) @@ -114,11 +112,7 @@ func TestRunGroupMultiErrorHandling(t *testing.T) { err1 = errors.New("cfg1 failed") err2 = errors.New("cfg2 failed") err3 = errors.New("cfg3 failed") - - mErr = multierror.SetFormatter( - multierror.Append(nil, err1, err2, err3), - multierror.ListFormatFunc, - ) + mErr = fmt.Errorf("3 errors occured:\n%w", errors.Join(err1, err2, err3)) cfg1 = failingConfig{e: err1} cfg2 = failingConfig{e: err2} From 37f096a671856128395cc775a99fc8b86fa1ac72 Mon Sep 17 00:00:00 2001 From: Ignasi Barrera Date: Fri, 16 Feb 2024 13:13:47 +0100 Subject: [PATCH 2/3] upgrade Go and revert err types --- .github/workflows/ci.yaml | 10 ++++------ group.go | 10 ++++++++-- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 4e33331..c0b852b 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -11,17 +11,15 @@ jobs: strategy: matrix: go-version: - - 1.16.x - - 1.17.x - - 1.18.x - - 1.19.x - 1.20.x + - 1.21.x + - 1.22.x os: - ubuntu-latest runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v3 - - uses: actions/setup-go@v4 + - uses: actions/checkout@v4 + - uses: actions/setup-go@v5 with: go-version: ${{ matrix.go-version }} - run: go test ./... diff --git a/group.go b/group.go index 84fb43f..03f45af 100644 --- a/group.go +++ b/group.go @@ -39,16 +39,22 @@ import ( // name in HelpText strings. const BinaryName = "{{.Name}}" +// Error allows for creating constant errors instead of sentinel ones. +type Error string + +// Error implements error. +func (e Error) Error() string { return string(e) } + // ErrBailEarlyRequest is returned when a call to RunConfig was successful but // signals that the application should exit in success immediately. // It is typically returned on --version and --help requests that have been // served. It can and should be used for custom config phase situations where // the job of the application is done. -var ErrBailEarlyRequest = errors.New("exit request from flag handler") +const ErrBailEarlyRequest = Error("exit request from flag handler") // ErrRequestedShutdown can be used by Service implementations to gracefully // request a shutdown of the application. Group will then exit without errors. -var ErrRequestedShutdown = errors.New("shutdown requested") +const ErrRequestedShutdown = Error("shutdown requested") // FlagSet holds a pflag.FlagSet as well as an exported Name variable for // allowing improved help usage information. From cad5ee6bb85b4a8f600b8955ae2cfbccc148013b Mon Sep 17 00:00:00 2001 From: Ignasi Barrera Date: Fri, 16 Feb 2024 13:19:53 +0100 Subject: [PATCH 3/3] cosmetic change --- group.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/group.go b/group.go index 03f45af..7877674 100644 --- a/group.go +++ b/group.go @@ -50,11 +50,11 @@ func (e Error) Error() string { return string(e) } // It is typically returned on --version and --help requests that have been // served. It can and should be used for custom config phase situations where // the job of the application is done. -const ErrBailEarlyRequest = Error("exit request from flag handler") +const ErrBailEarlyRequest Error = "exit request from flag handler" // ErrRequestedShutdown can be used by Service implementations to gracefully // request a shutdown of the application. Group will then exit without errors. -const ErrRequestedShutdown = Error("shutdown requested") +const ErrRequestedShutdown Error = "shutdown requested" // FlagSet holds a pflag.FlagSet as well as an exported Name variable for // allowing improved help usage information.