summaryrefslogtreecommitdiffstats
path: root/dependencies/pkg/mod/go.uber.org/multierr@v1.10.0
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-13 11:40:59 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-13 11:40:59 +0000
commitbc4e624732bd51c0dd1e9529cf228e8c23127732 (patch)
treed95dab8960e9d02d3b95f8653074ad2e54ca207c /dependencies/pkg/mod/go.uber.org/multierr@v1.10.0
parentInitial commit. (diff)
downloadicingadb-bc4e624732bd51c0dd1e9529cf228e8c23127732.tar.xz
icingadb-bc4e624732bd51c0dd1e9529cf228e8c23127732.zip
Adding upstream version 1.1.1.upstream/1.1.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'dependencies/pkg/mod/go.uber.org/multierr@v1.10.0')
-rw-r--r--dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/.codecov.yml15
-rw-r--r--dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/.github/workflows/fossa.yaml17
-rw-r--r--dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/.github/workflows/go.yml49
-rw-r--r--dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/.gitignore4
-rw-r--r--dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/CHANGELOG.md88
-rw-r--r--dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/LICENSE.txt19
-rw-r--r--dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/Makefile38
-rw-r--r--dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/README.md43
-rw-r--r--dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/appendinvoke_example_test.go73
-rw-r--r--dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/benchmarks_test.go127
-rw-r--r--dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/error.go652
-rw-r--r--dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/error_ext_test.go142
-rw-r--r--dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/error_post_go120.go29
-rw-r--r--dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/error_pre_go120.go59
-rw-r--r--dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/error_test.go717
-rw-r--r--dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/example_test.go124
-rw-r--r--dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/go.mod11
-rw-r--r--dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/go.sum13
18 files changed, 2220 insertions, 0 deletions
diff --git a/dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/.codecov.yml b/dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/.codecov.yml
new file mode 100644
index 0000000..6d4d1be
--- /dev/null
+++ b/dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/.codecov.yml
@@ -0,0 +1,15 @@
+coverage:
+ range: 80..100
+ round: down
+ precision: 2
+
+ status:
+ project: # measuring the overall project coverage
+ default: # context, you can create multiple ones with custom titles
+ enabled: yes # must be yes|true to enable this status
+ target: 100 # specify the target coverage for each commit status
+ # option: "auto" (must increase from parent commit or pull request base)
+ # option: "X%" a static target percentage to hit
+ if_not_found: success # if parent is not found report status as success, error, or failure
+ if_ci_failed: error # if ci fails report status as success, error, or failure
+
diff --git a/dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/.github/workflows/fossa.yaml b/dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/.github/workflows/fossa.yaml
new file mode 100644
index 0000000..86e6db7
--- /dev/null
+++ b/dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/.github/workflows/fossa.yaml
@@ -0,0 +1,17 @@
+name: FOSSA Analysis
+on: push
+
+jobs:
+
+ build:
+ runs-on: ubuntu-latest
+ if: github.repository_owner == 'uber-go'
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@v2
+
+ - name: FOSSA analysis
+ uses: fossas/fossa-action@v1
+ with:
+ api-key: ${{ secrets.FOSSA_API_KEY }}
+
diff --git a/dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/.github/workflows/go.yml b/dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/.github/workflows/go.yml
new file mode 100644
index 0000000..23c78ab
--- /dev/null
+++ b/dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/.github/workflows/go.yml
@@ -0,0 +1,49 @@
+name: Go
+
+on:
+ push:
+ branches: ['*']
+ tags: ['v*']
+ pull_request:
+ branches: ['*']
+
+jobs:
+
+ build:
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ go: ["1.19.x", "1.20.x"]
+ include:
+ - go: 1.20.x
+ latest: true
+
+ steps:
+ - name: Setup Go
+ uses: actions/setup-go@v2
+ with:
+ go-version: ${{ matrix.go }}
+
+ - name: Checkout code
+ uses: actions/checkout@v2
+
+ - name: Load cached dependencies
+ uses: actions/cache@v1
+ with:
+ path: ~/go/pkg/mod
+ key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
+ restore-keys: |
+ ${{ runner.os }}-go-
+
+ - name: Download Dependencies
+ run: go mod download
+
+ - name: Lint
+ if: matrix.latest
+ run: make lint
+
+ - name: Test
+ run: make cover
+
+ - name: Upload coverage to codecov.io
+ uses: codecov/codecov-action@v1
diff --git a/dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/.gitignore b/dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/.gitignore
new file mode 100644
index 0000000..b9a05e3
--- /dev/null
+++ b/dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/.gitignore
@@ -0,0 +1,4 @@
+/vendor
+cover.html
+cover.out
+/bin
diff --git a/dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/CHANGELOG.md b/dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/CHANGELOG.md
new file mode 100644
index 0000000..cfd2e6a
--- /dev/null
+++ b/dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/CHANGELOG.md
@@ -0,0 +1,88 @@
+Releases
+========
+
+v1.10.0 (2023-03-08)
+====================
+
+- Comply with Go 1.20's multiple-error interface.
+- Drop Go 1.18 support.
+ Per the support policy, only Go 1.19 and 1.20 are supported now.
+- Drop all non-test external dependencies.
+
+v1.9.0 (2022-12-12)
+===================
+
+- Add `AppendFunc` that allow passsing functions to similar to
+ `AppendInvoke`.
+
+- Bump up yaml.v3 dependency to 3.0.1.
+
+v1.8.0 (2022-02-28)
+===================
+
+- `Combine`: perform zero allocations when there are no errors.
+
+
+v1.7.0 (2021-05-06)
+===================
+
+- Add `AppendInvoke` to append into errors from `defer` blocks.
+
+
+v1.6.0 (2020-09-14)
+===================
+
+- Actually drop library dependency on development-time tooling.
+
+
+v1.5.0 (2020-02-24)
+===================
+
+- Drop library dependency on development-time tooling.
+
+
+v1.4.0 (2019-11-04)
+===================
+
+- Add `AppendInto` function to more ergonomically build errors inside a
+ loop.
+
+
+v1.3.0 (2019-10-29)
+===================
+
+- Switch to Go modules.
+
+
+v1.2.0 (2019-09-26)
+===================
+
+- Support extracting and matching against wrapped errors with `errors.As`
+ and `errors.Is`.
+
+
+v1.1.0 (2017-06-30)
+===================
+
+- Added an `Errors(error) []error` function to extract the underlying list of
+ errors for a multierr error.
+
+
+v1.0.0 (2017-05-31)
+===================
+
+No changes since v0.2.0. This release is committing to making no breaking
+changes to the current API in the 1.X series.
+
+
+v0.2.0 (2017-04-11)
+===================
+
+- Repeatedly appending to the same error is now faster due to fewer
+ allocations.
+
+
+v0.1.0 (2017-31-03)
+===================
+
+- Initial release
diff --git a/dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/LICENSE.txt b/dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/LICENSE.txt
new file mode 100644
index 0000000..413e30f
--- /dev/null
+++ b/dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/LICENSE.txt
@@ -0,0 +1,19 @@
+Copyright (c) 2017-2021 Uber Technologies, Inc.
+
+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.
diff --git a/dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/Makefile b/dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/Makefile
new file mode 100644
index 0000000..dcb6fe7
--- /dev/null
+++ b/dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/Makefile
@@ -0,0 +1,38 @@
+# Directory to put `go install`ed binaries in.
+export GOBIN ?= $(shell pwd)/bin
+
+GO_FILES := $(shell \
+ find . '(' -path '*/.*' -o -path './vendor' ')' -prune \
+ -o -name '*.go' -print | cut -b3-)
+
+.PHONY: build
+build:
+ go build ./...
+
+.PHONY: test
+test:
+ go test -race ./...
+
+.PHONY: gofmt
+gofmt:
+ $(eval FMT_LOG := $(shell mktemp -t gofmt.XXXXX))
+ @gofmt -e -s -l $(GO_FILES) > $(FMT_LOG) || true
+ @[ ! -s "$(FMT_LOG)" ] || (echo "gofmt failed:" | cat - $(FMT_LOG) && false)
+
+.PHONY: golint
+golint:
+ @cd tools && go install golang.org/x/lint/golint
+ @$(GOBIN)/golint ./...
+
+.PHONY: staticcheck
+staticcheck:
+ @cd tools && go install honnef.co/go/tools/cmd/staticcheck
+ @$(GOBIN)/staticcheck ./...
+
+.PHONY: lint
+lint: gofmt golint staticcheck
+
+.PHONY: cover
+cover:
+ go test -race -coverprofile=cover.out -coverpkg=./... -v ./...
+ go tool cover -html=cover.out -o cover.html
diff --git a/dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/README.md b/dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/README.md
new file mode 100644
index 0000000..5ab6ac4
--- /dev/null
+++ b/dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/README.md
@@ -0,0 +1,43 @@
+# multierr [![GoDoc][doc-img]][doc] [![Build Status][ci-img]][ci] [![Coverage Status][cov-img]][cov]
+
+`multierr` allows combining one or more Go `error`s together.
+
+## Features
+
+- **Idiomatic**:
+ multierr follows best practices in Go, and keeps your code idiomatic.
+ - It keeps the underlying error type hidden,
+ allowing you to deal in `error` values exclusively.
+ - It provides APIs to safely append into an error from a `defer` statement.
+- **Performant**:
+ multierr is optimized for performance:
+ - It avoids allocations where possible.
+ - It utilizes slice resizing semantics to optimize common cases
+ like appending into the same error object from a loop.
+- **Interoperable**:
+ multierr interoperates with the Go standard library's error APIs seamlessly:
+ - The `errors.Is` and `errors.As` functions *just work*.
+- **Lightweight**:
+ multierr comes with virtually no dependencies.
+
+## Installation
+
+```bash
+go get -u go.uber.org/multierr@latest
+```
+
+## Status
+
+Stable: No breaking changes will be made before 2.0.
+
+-------------------------------------------------------------------------------
+
+Released under the [MIT License].
+
+[MIT License]: LICENSE.txt
+[doc-img]: https://pkg.go.dev/badge/go.uber.org/multierr
+[doc]: https://pkg.go.dev/go.uber.org/multierr
+[ci-img]: https://github.com/uber-go/multierr/actions/workflows/go.yml/badge.svg
+[cov-img]: https://codecov.io/gh/uber-go/multierr/branch/master/graph/badge.svg
+[ci]: https://github.com/uber-go/multierr/actions/workflows/go.yml
+[cov]: https://codecov.io/gh/uber-go/multierr
diff --git a/dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/appendinvoke_example_test.go b/dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/appendinvoke_example_test.go
new file mode 100644
index 0000000..f8b674b
--- /dev/null
+++ b/dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/appendinvoke_example_test.go
@@ -0,0 +1,73 @@
+// Copyright (c) 2021 Uber Technologies, Inc.
+//
+// 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 multierr_test
+
+import (
+ "fmt"
+ "log"
+ "os"
+ "path/filepath"
+
+ "go.uber.org/multierr"
+)
+
+func ExampleAppendInvoke() {
+ if err := run(); err != nil {
+ log.Fatal(err)
+ }
+}
+
+func run() (err error) {
+ dir, err := os.MkdirTemp("", "multierr")
+ // We create a temporary directory and defer its deletion when this
+ // function returns.
+ //
+ // If we failed to delete the temporary directory, we append its
+ // failure into the returned value with multierr.AppendInvoke.
+ //
+ // This uses a custom invoker that we implement below.
+ defer multierr.AppendInvoke(&err, RemoveAll(dir))
+
+ path := filepath.Join(dir, "example.txt")
+ f, err := os.Create(path)
+ if err != nil {
+ return err
+ }
+ // Similarly, we defer closing the open file when the function returns,
+ // and appends its failure, if any, into the returned error.
+ //
+ // This uses the multierr.Close invoker included in multierr.
+ defer multierr.AppendInvoke(&err, multierr.Close(f))
+
+ if _, err := fmt.Fprintln(f, "hello"); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+// RemoveAll is a multierr.Invoker that deletes the provided directory and all
+// of its contents.
+type RemoveAll string
+
+func (r RemoveAll) Invoke() error {
+ return os.RemoveAll(string(r))
+}
diff --git a/dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/benchmarks_test.go b/dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/benchmarks_test.go
new file mode 100644
index 0000000..562d3bc
--- /dev/null
+++ b/dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/benchmarks_test.go
@@ -0,0 +1,127 @@
+// Copyright (c) 2017 Uber Technologies, Inc.
+//
+// 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 multierr
+
+import (
+ "errors"
+ "fmt"
+ "testing"
+)
+
+func BenchmarkAppend(b *testing.B) {
+ errorTypes := []struct {
+ name string
+ err error
+ }{
+ {
+ name: "nil",
+ err: nil,
+ },
+ {
+ name: "single error",
+ err: errors.New("test"),
+ },
+ {
+ name: "multiple errors",
+ err: appendN(nil, errors.New("err"), 10),
+ },
+ }
+
+ for _, initial := range errorTypes {
+ for _, v := range errorTypes {
+ msg := fmt.Sprintf("append %v to %v", v.name, initial.name)
+ b.Run(msg, func(b *testing.B) {
+ for _, appends := range []int{1, 2, 10} {
+ b.Run(fmt.Sprint(appends), func(b *testing.B) {
+ for i := 0; i < b.N; i++ {
+ appendN(initial.err, v.err, appends)
+ }
+ })
+ }
+ })
+ }
+ }
+}
+
+func BenchmarkCombine(b *testing.B) {
+ b.Run("inline 1", func(b *testing.B) {
+ var x error
+ for i := 0; i < b.N; i++ {
+ Combine(x)
+ }
+ })
+
+ b.Run("inline 2", func(b *testing.B) {
+ var x, y error
+ for i := 0; i < b.N; i++ {
+ Combine(x, y)
+ }
+ })
+
+ b.Run("inline 3 no error", func(b *testing.B) {
+ var x, y, z error
+ for i := 0; i < b.N; i++ {
+ Combine(x, y, z)
+ }
+ })
+
+ b.Run("inline 3 one error", func(b *testing.B) {
+ var x, y, z error
+ z = fmt.Errorf("failed")
+ for i := 0; i < b.N; i++ {
+ Combine(x, y, z)
+ }
+ })
+
+ b.Run("inline 3 multiple errors", func(b *testing.B) {
+ var x, y, z error
+ z = fmt.Errorf("failed3")
+ y = fmt.Errorf("failed2")
+ x = fmt.Errorf("failed")
+ for i := 0; i < b.N; i++ {
+ Combine(x, y, z)
+ }
+ })
+
+ b.Run("slice 100 no errors", func(b *testing.B) {
+ errs := make([]error, 100)
+ for i := 0; i < b.N; i++ {
+ Combine(errs...)
+ }
+ })
+
+ b.Run("slice 100 one error", func(b *testing.B) {
+ errs := make([]error, 100)
+ errs[len(errs)-1] = fmt.Errorf("failed")
+ for i := 0; i < b.N; i++ {
+ Combine(errs...)
+ }
+ })
+
+ b.Run("slice 100 multi error", func(b *testing.B) {
+ errs := make([]error, 100)
+ errs[0] = fmt.Errorf("failed1")
+ errs[len(errs)-1] = fmt.Errorf("failed2")
+ for i := 0; i < b.N; i++ {
+ Combine(errs...)
+ }
+ })
+}
diff --git a/dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/error.go b/dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/error.go
new file mode 100644
index 0000000..4ee4b9f
--- /dev/null
+++ b/dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/error.go
@@ -0,0 +1,652 @@
+// Copyright (c) 2017-2023 Uber Technologies, Inc.
+//
+// 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 multierr allows combining one or more errors together.
+//
+// # Overview
+//
+// Errors can be combined with the use of the Combine function.
+//
+// multierr.Combine(
+// reader.Close(),
+// writer.Close(),
+// conn.Close(),
+// )
+//
+// If only two errors are being combined, the Append function may be used
+// instead.
+//
+// err = multierr.Append(reader.Close(), writer.Close())
+//
+// The underlying list of errors for a returned error object may be retrieved
+// with the Errors function.
+//
+// errors := multierr.Errors(err)
+// if len(errors) > 0 {
+// fmt.Println("The following errors occurred:", errors)
+// }
+//
+// # Appending from a loop
+//
+// You sometimes need to append into an error from a loop.
+//
+// var err error
+// for _, item := range items {
+// err = multierr.Append(err, process(item))
+// }
+//
+// Cases like this may require knowledge of whether an individual instance
+// failed. This usually requires introduction of a new variable.
+//
+// var err error
+// for _, item := range items {
+// if perr := process(item); perr != nil {
+// log.Warn("skipping item", item)
+// err = multierr.Append(err, perr)
+// }
+// }
+//
+// multierr includes AppendInto to simplify cases like this.
+//
+// var err error
+// for _, item := range items {
+// if multierr.AppendInto(&err, process(item)) {
+// log.Warn("skipping item", item)
+// }
+// }
+//
+// This will append the error into the err variable, and return true if that
+// individual error was non-nil.
+//
+// See [AppendInto] for more information.
+//
+// # Deferred Functions
+//
+// Go makes it possible to modify the return value of a function in a defer
+// block if the function was using named returns. This makes it possible to
+// record resource cleanup failures from deferred blocks.
+//
+// func sendRequest(req Request) (err error) {
+// conn, err := openConnection()
+// if err != nil {
+// return err
+// }
+// defer func() {
+// err = multierr.Append(err, conn.Close())
+// }()
+// // ...
+// }
+//
+// multierr provides the Invoker type and AppendInvoke function to make cases
+// like the above simpler and obviate the need for a closure. The following is
+// roughly equivalent to the example above.
+//
+// func sendRequest(req Request) (err error) {
+// conn, err := openConnection()
+// if err != nil {
+// return err
+// }
+// defer multierr.AppendInvoke(&err, multierr.Close(conn))
+// // ...
+// }
+//
+// See [AppendInvoke] and [Invoker] for more information.
+//
+// NOTE: If you're modifying an error from inside a defer, you MUST use a named
+// return value for that function.
+//
+// # Advanced Usage
+//
+// Errors returned by Combine and Append MAY implement the following
+// interface.
+//
+// type errorGroup interface {
+// // Returns a slice containing the underlying list of errors.
+// //
+// // This slice MUST NOT be modified by the caller.
+// Errors() []error
+// }
+//
+// Note that if you need access to list of errors behind a multierr error, you
+// should prefer using the Errors function. That said, if you need cheap
+// read-only access to the underlying errors slice, you can attempt to cast
+// the error to this interface. You MUST handle the failure case gracefully
+// because errors returned by Combine and Append are not guaranteed to
+// implement this interface.
+//
+// var errors []error
+// group, ok := err.(errorGroup)
+// if ok {
+// errors = group.Errors()
+// } else {
+// errors = []error{err}
+// }
+package multierr // import "go.uber.org/multierr"
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+ "strings"
+ "sync"
+ "sync/atomic"
+)
+
+var (
+ // Separator for single-line error messages.
+ _singlelineSeparator = []byte("; ")
+
+ // Prefix for multi-line messages
+ _multilinePrefix = []byte("the following errors occurred:")
+
+ // Prefix for the first and following lines of an item in a list of
+ // multi-line error messages.
+ //
+ // For example, if a single item is:
+ //
+ // foo
+ // bar
+ //
+ // It will become,
+ //
+ // - foo
+ // bar
+ _multilineSeparator = []byte("\n - ")
+ _multilineIndent = []byte(" ")
+)
+
+// _bufferPool is a pool of bytes.Buffers.
+var _bufferPool = sync.Pool{
+ New: func() interface{} {
+ return &bytes.Buffer{}
+ },
+}
+
+type errorGroup interface {
+ Errors() []error
+}
+
+// Errors returns a slice containing zero or more errors that the supplied
+// error is composed of. If the error is nil, a nil slice is returned.
+//
+// err := multierr.Append(r.Close(), w.Close())
+// errors := multierr.Errors(err)
+//
+// If the error is not composed of other errors, the returned slice contains
+// just the error that was passed in.
+//
+// Callers of this function are free to modify the returned slice.
+func Errors(err error) []error {
+ if err == nil {
+ return nil
+ }
+
+ // Note that we're casting to multiError, not errorGroup. Our contract is
+ // that returned errors MAY implement errorGroup. Errors, however, only
+ // has special behavior for multierr-specific error objects.
+ //
+ // This behavior can be expanded in the future but I think it's prudent to
+ // start with as little as possible in terms of contract and possibility
+ // of misuse.
+ eg, ok := err.(*multiError)
+ if !ok {
+ return []error{err}
+ }
+
+ return append(([]error)(nil), eg.Errors()...)
+}
+
+// multiError is an error that holds one or more errors.
+//
+// An instance of this is guaranteed to be non-empty and flattened. That is,
+// none of the errors inside multiError are other multiErrors.
+//
+// multiError formats to a semi-colon delimited list of error messages with
+// %v and with a more readable multi-line format with %+v.
+type multiError struct {
+ copyNeeded atomic.Bool
+ errors []error
+}
+
+var _ errorGroup = (*multiError)(nil)
+
+// Errors returns the list of underlying errors.
+//
+// This slice MUST NOT be modified.
+func (merr *multiError) Errors() []error {
+ if merr == nil {
+ return nil
+ }
+ return merr.errors
+}
+
+func (merr *multiError) Error() string {
+ if merr == nil {
+ return ""
+ }
+
+ buff := _bufferPool.Get().(*bytes.Buffer)
+ buff.Reset()
+
+ merr.writeSingleline(buff)
+
+ result := buff.String()
+ _bufferPool.Put(buff)
+ return result
+}
+
+func (merr *multiError) Format(f fmt.State, c rune) {
+ if c == 'v' && f.Flag('+') {
+ merr.writeMultiline(f)
+ } else {
+ merr.writeSingleline(f)
+ }
+}
+
+func (merr *multiError) writeSingleline(w io.Writer) {
+ first := true
+ for _, item := range merr.errors {
+ if first {
+ first = false
+ } else {
+ w.Write(_singlelineSeparator)
+ }
+ io.WriteString(w, item.Error())
+ }
+}
+
+func (merr *multiError) writeMultiline(w io.Writer) {
+ w.Write(_multilinePrefix)
+ for _, item := range merr.errors {
+ w.Write(_multilineSeparator)
+ writePrefixLine(w, _multilineIndent, fmt.Sprintf("%+v", item))
+ }
+}
+
+// Writes s to the writer with the given prefix added before each line after
+// the first.
+func writePrefixLine(w io.Writer, prefix []byte, s string) {
+ first := true
+ for len(s) > 0 {
+ if first {
+ first = false
+ } else {
+ w.Write(prefix)
+ }
+
+ idx := strings.IndexByte(s, '\n')
+ if idx < 0 {
+ idx = len(s) - 1
+ }
+
+ io.WriteString(w, s[:idx+1])
+ s = s[idx+1:]
+ }
+}
+
+type inspectResult struct {
+ // Number of top-level non-nil errors
+ Count int
+
+ // Total number of errors including multiErrors
+ Capacity int
+
+ // Index of the first non-nil error in the list. Value is meaningless if
+ // Count is zero.
+ FirstErrorIdx int
+
+ // Whether the list contains at least one multiError
+ ContainsMultiError bool
+}
+
+// Inspects the given slice of errors so that we can efficiently allocate
+// space for it.
+func inspect(errors []error) (res inspectResult) {
+ first := true
+ for i, err := range errors {
+ if err == nil {
+ continue
+ }
+
+ res.Count++
+ if first {
+ first = false
+ res.FirstErrorIdx = i
+ }
+
+ if merr, ok := err.(*multiError); ok {
+ res.Capacity += len(merr.errors)
+ res.ContainsMultiError = true
+ } else {
+ res.Capacity++
+ }
+ }
+ return
+}
+
+// fromSlice converts the given list of errors into a single error.
+func fromSlice(errors []error) error {
+ // Don't pay to inspect small slices.
+ switch len(errors) {
+ case 0:
+ return nil
+ case 1:
+ return errors[0]
+ }
+
+ res := inspect(errors)
+ switch res.Count {
+ case 0:
+ return nil
+ case 1:
+ // only one non-nil entry
+ return errors[res.FirstErrorIdx]
+ case len(errors):
+ if !res.ContainsMultiError {
+ // Error list is flat. Make a copy of it
+ // Otherwise "errors" escapes to the heap
+ // unconditionally for all other cases.
+ // This lets us optimize for the "no errors" case.
+ out := append(([]error)(nil), errors...)
+ return &multiError{errors: out}
+ }
+ }
+
+ nonNilErrs := make([]error, 0, res.Capacity)
+ for _, err := range errors[res.FirstErrorIdx:] {
+ if err == nil {
+ continue
+ }
+
+ if nested, ok := err.(*multiError); ok {
+ nonNilErrs = append(nonNilErrs, nested.errors...)
+ } else {
+ nonNilErrs = append(nonNilErrs, err)
+ }
+ }
+
+ return &multiError{errors: nonNilErrs}
+}
+
+// Combine combines the passed errors into a single error.
+//
+// If zero arguments were passed or if all items are nil, a nil error is
+// returned.
+//
+// Combine(nil, nil) // == nil
+//
+// If only a single error was passed, it is returned as-is.
+//
+// Combine(err) // == err
+//
+// Combine skips over nil arguments so this function may be used to combine
+// together errors from operations that fail independently of each other.
+//
+// multierr.Combine(
+// reader.Close(),
+// writer.Close(),
+// pipe.Close(),
+// )
+//
+// If any of the passed errors is a multierr error, it will be flattened along
+// with the other errors.
+//
+// multierr.Combine(multierr.Combine(err1, err2), err3)
+// // is the same as
+// multierr.Combine(err1, err2, err3)
+//
+// The returned error formats into a readable multi-line error message if
+// formatted with %+v.
+//
+// fmt.Sprintf("%+v", multierr.Combine(err1, err2))
+func Combine(errors ...error) error {
+ return fromSlice(errors)
+}
+
+// Append appends the given errors together. Either value may be nil.
+//
+// This function is a specialization of Combine for the common case where
+// there are only two errors.
+//
+// err = multierr.Append(reader.Close(), writer.Close())
+//
+// The following pattern may also be used to record failure of deferred
+// operations without losing information about the original error.
+//
+// func doSomething(..) (err error) {
+// f := acquireResource()
+// defer func() {
+// err = multierr.Append(err, f.Close())
+// }()
+//
+// Note that the variable MUST be a named return to append an error to it from
+// the defer statement. See also [AppendInvoke].
+func Append(left error, right error) error {
+ switch {
+ case left == nil:
+ return right
+ case right == nil:
+ return left
+ }
+
+ if _, ok := right.(*multiError); !ok {
+ if l, ok := left.(*multiError); ok && !l.copyNeeded.Swap(true) {
+ // Common case where the error on the left is constantly being
+ // appended to.
+ errs := append(l.errors, right)
+ return &multiError{errors: errs}
+ } else if !ok {
+ // Both errors are single errors.
+ return &multiError{errors: []error{left, right}}
+ }
+ }
+
+ // Either right or both, left and right, are multiErrors. Rely on usual
+ // expensive logic.
+ errors := [2]error{left, right}
+ return fromSlice(errors[0:])
+}
+
+// AppendInto appends an error into the destination of an error pointer and
+// returns whether the error being appended was non-nil.
+//
+// var err error
+// multierr.AppendInto(&err, r.Close())
+// multierr.AppendInto(&err, w.Close())
+//
+// The above is equivalent to,
+//
+// err := multierr.Append(r.Close(), w.Close())
+//
+// As AppendInto reports whether the provided error was non-nil, it may be
+// used to build a multierr error in a loop more ergonomically. For example:
+//
+// var err error
+// for line := range lines {
+// var item Item
+// if multierr.AppendInto(&err, parse(line, &item)) {
+// continue
+// }
+// items = append(items, item)
+// }
+//
+// Compare this with a version that relies solely on Append:
+//
+// var err error
+// for line := range lines {
+// var item Item
+// if parseErr := parse(line, &item); parseErr != nil {
+// err = multierr.Append(err, parseErr)
+// continue
+// }
+// items = append(items, item)
+// }
+func AppendInto(into *error, err error) (errored bool) {
+ if into == nil {
+ // We panic if 'into' is nil. This is not documented above
+ // because suggesting that the pointer must be non-nil may
+ // confuse users into thinking that the error that it points
+ // to must be non-nil.
+ panic("misuse of multierr.AppendInto: into pointer must not be nil")
+ }
+
+ if err == nil {
+ return false
+ }
+ *into = Append(*into, err)
+ return true
+}
+
+// Invoker is an operation that may fail with an error. Use it with
+// AppendInvoke to append the result of calling the function into an error.
+// This allows you to conveniently defer capture of failing operations.
+//
+// See also, [Close] and [Invoke].
+type Invoker interface {
+ Invoke() error
+}
+
+// Invoke wraps a function which may fail with an error to match the Invoker
+// interface. Use it to supply functions matching this signature to
+// AppendInvoke.
+//
+// For example,
+//
+// func processReader(r io.Reader) (err error) {
+// scanner := bufio.NewScanner(r)
+// defer multierr.AppendInvoke(&err, multierr.Invoke(scanner.Err))
+// for scanner.Scan() {
+// // ...
+// }
+// // ...
+// }
+//
+// In this example, the following line will construct the Invoker right away,
+// but defer the invocation of scanner.Err() until the function returns.
+//
+// defer multierr.AppendInvoke(&err, multierr.Invoke(scanner.Err))
+//
+// Note that the error you're appending to from the defer statement MUST be a
+// named return.
+type Invoke func() error
+
+// Invoke calls the supplied function and returns its result.
+func (i Invoke) Invoke() error { return i() }
+
+// Close builds an Invoker that closes the provided io.Closer. Use it with
+// AppendInvoke to close io.Closers and append their results into an error.
+//
+// For example,
+//
+// func processFile(path string) (err error) {
+// f, err := os.Open(path)
+// if err != nil {
+// return err
+// }
+// defer multierr.AppendInvoke(&err, multierr.Close(f))
+// return processReader(f)
+// }
+//
+// In this example, multierr.Close will construct the Invoker right away, but
+// defer the invocation of f.Close until the function returns.
+//
+// defer multierr.AppendInvoke(&err, multierr.Close(f))
+//
+// Note that the error you're appending to from the defer statement MUST be a
+// named return.
+func Close(closer io.Closer) Invoker {
+ return Invoke(closer.Close)
+}
+
+// AppendInvoke appends the result of calling the given Invoker into the
+// provided error pointer. Use it with named returns to safely defer
+// invocation of fallible operations until a function returns, and capture the
+// resulting errors.
+//
+// func doSomething(...) (err error) {
+// // ...
+// f, err := openFile(..)
+// if err != nil {
+// return err
+// }
+//
+// // multierr will call f.Close() when this function returns and
+// // if the operation fails, its append its error into the
+// // returned error.
+// defer multierr.AppendInvoke(&err, multierr.Close(f))
+//
+// scanner := bufio.NewScanner(f)
+// // Similarly, this scheduled scanner.Err to be called and
+// // inspected when the function returns and append its error
+// // into the returned error.
+// defer multierr.AppendInvoke(&err, multierr.Invoke(scanner.Err))
+//
+// // ...
+// }
+//
+// NOTE: If used with a defer, the error variable MUST be a named return.
+//
+// Without defer, AppendInvoke behaves exactly like AppendInto.
+//
+// err := // ...
+// multierr.AppendInvoke(&err, mutltierr.Invoke(foo))
+//
+// // ...is roughly equivalent to...
+//
+// err := // ...
+// multierr.AppendInto(&err, foo())
+//
+// The advantage of the indirection introduced by Invoker is to make it easy
+// to defer the invocation of a function. Without this indirection, the
+// invoked function will be evaluated at the time of the defer block rather
+// than when the function returns.
+//
+// // BAD: This is likely not what the caller intended. This will evaluate
+// // foo() right away and append its result into the error when the
+// // function returns.
+// defer multierr.AppendInto(&err, foo())
+//
+// // GOOD: This will defer invocation of foo unutil the function returns.
+// defer multierr.AppendInvoke(&err, multierr.Invoke(foo))
+//
+// multierr provides a few Invoker implementations out of the box for
+// convenience. See [Invoker] for more information.
+func AppendInvoke(into *error, invoker Invoker) {
+ AppendInto(into, invoker.Invoke())
+}
+
+// AppendFunc is a shorthand for [AppendInvoke].
+// It allows using function or method value directly
+// without having to wrap it into an [Invoker] interface.
+//
+// func doSomething(...) (err error) {
+// w, err := startWorker(...)
+// if err != nil {
+// return err
+// }
+//
+// // multierr will call w.Stop() when this function returns and
+// // if the operation fails, it appends its error into the
+// // returned error.
+// defer multierr.AppendFunc(&err, w.Stop)
+// }
+func AppendFunc(into *error, fn func() error) {
+ AppendInvoke(into, Invoke(fn))
+}
diff --git a/dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/error_ext_test.go b/dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/error_ext_test.go
new file mode 100644
index 0000000..9936e36
--- /dev/null
+++ b/dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/error_ext_test.go
@@ -0,0 +1,142 @@
+// Copyright (c) 2020 Uber Technologies, Inc.
+//
+// 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 multierr_test
+
+import (
+ "errors"
+ "os"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+ "go.uber.org/multierr"
+)
+
+type errGreatSadness struct{ id int }
+
+func (errGreatSadness) Error() string {
+ return "great sadness"
+}
+
+type errUnprecedentedFailure struct{ id int }
+
+func (errUnprecedentedFailure) Error() string {
+ return "unprecedented failure"
+}
+
+func (e errUnprecedentedFailure) Unwrap() error {
+ return errRootCause{e.id}
+}
+
+type errRootCause struct{ i int }
+
+func (errRootCause) Error() string {
+ return "root cause"
+}
+
+func TestErrorsWrapping(t *testing.T) {
+ err := multierr.Append(
+ errGreatSadness{42},
+ errUnprecedentedFailure{43},
+ )
+
+ t.Run("left", func(t *testing.T) {
+ t.Run("As", func(t *testing.T) {
+ var got errGreatSadness
+ require.True(t, errors.As(err, &got))
+ assert.Equal(t, 42, got.id)
+ })
+
+ t.Run("Is", func(t *testing.T) {
+ assert.False(t, errors.Is(err, errGreatSadness{41}))
+ assert.True(t, errors.Is(err, errGreatSadness{42}))
+ })
+ })
+
+ t.Run("right", func(t *testing.T) {
+ t.Run("As", func(t *testing.T) {
+ var got errUnprecedentedFailure
+ require.True(t, errors.As(err, &got))
+ assert.Equal(t, 43, got.id)
+ })
+
+ t.Run("Is", func(t *testing.T) {
+ assert.False(t, errors.Is(err, errUnprecedentedFailure{42}))
+ assert.True(t, errors.Is(err, errUnprecedentedFailure{43}))
+ })
+ })
+
+ t.Run("top-level", func(t *testing.T) {
+ t.Run("As", func(t *testing.T) {
+ var got interface{ Errors() []error }
+ require.True(t, errors.As(err, &got))
+ assert.Len(t, got.Errors(), 2)
+ })
+
+ t.Run("Is", func(t *testing.T) {
+ assert.True(t, errors.Is(err, err))
+ })
+ })
+
+ t.Run("root cause", func(t *testing.T) {
+ t.Run("As", func(t *testing.T) {
+ var got errRootCause
+ require.True(t, errors.As(err, &got))
+ assert.Equal(t, 43, got.i)
+ })
+
+ t.Run("Is", func(t *testing.T) {
+ assert.False(t, errors.Is(err, errRootCause{42}))
+ assert.True(t, errors.Is(err, errRootCause{43}))
+ })
+ })
+
+ t.Run("mismatch", func(t *testing.T) {
+ t.Run("As", func(t *testing.T) {
+ var got *os.PathError
+ assert.False(t, errors.As(err, &got))
+ })
+
+ t.Run("Is", func(t *testing.T) {
+ assert.False(t, errors.Is(err, errors.New("great sadness")))
+ })
+ })
+}
+
+func TestErrorsWrappingSameType(t *testing.T) {
+ err := multierr.Combine(
+ errGreatSadness{1},
+ errGreatSadness{2},
+ errGreatSadness{3},
+ )
+
+ t.Run("As returns first", func(t *testing.T) {
+ var got errGreatSadness
+ require.True(t, errors.As(err, &got))
+ assert.Equal(t, 1, got.id)
+ })
+
+ t.Run("Is matches all", func(t *testing.T) {
+ assert.True(t, errors.Is(err, errGreatSadness{1}))
+ assert.True(t, errors.Is(err, errGreatSadness{2}))
+ assert.True(t, errors.Is(err, errGreatSadness{3}))
+ })
+}
diff --git a/dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/error_post_go120.go b/dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/error_post_go120.go
new file mode 100644
index 0000000..0b00bec
--- /dev/null
+++ b/dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/error_post_go120.go
@@ -0,0 +1,29 @@
+// Copyright (c) 2017-2023 Uber Technologies, Inc.
+//
+// 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.
+
+//go:build go1.20
+// +build go1.20
+
+package multierr
+
+// Unwrap returns a list of errors wrapped by this multierr.
+func (merr *multiError) Unwrap() []error {
+ return merr.Errors()
+}
diff --git a/dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/error_pre_go120.go b/dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/error_pre_go120.go
new file mode 100644
index 0000000..8da10f1
--- /dev/null
+++ b/dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/error_pre_go120.go
@@ -0,0 +1,59 @@
+// Copyright (c) 2017-2023 Uber Technologies, Inc.
+//
+// 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.
+
+//go:build !go1.20
+// +build !go1.20
+
+package multierr
+
+import "errors"
+
+// Versions of Go before 1.20 did not support the Unwrap() []error method.
+// This provides a similar behavior by implementing the Is(..) and As(..)
+// methods.
+// See the errors.Join proposal for details:
+// https://github.com/golang/go/issues/53435
+
+// As attempts to find the first error in the error list that matches the type
+// of the value that target points to.
+//
+// This function allows errors.As to traverse the values stored on the
+// multierr error.
+func (merr *multiError) As(target interface{}) bool {
+ for _, err := range merr.Errors() {
+ if errors.As(err, target) {
+ return true
+ }
+ }
+ return false
+}
+
+// Is attempts to match the provided error against errors in the error list.
+//
+// This function allows errors.Is to traverse the values stored on the
+// multierr error.
+func (merr *multiError) Is(target error) bool {
+ for _, err := range merr.Errors() {
+ if errors.Is(err, target) {
+ return true
+ }
+ }
+ return false
+}
diff --git a/dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/error_test.go b/dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/error_test.go
new file mode 100644
index 0000000..39ca313
--- /dev/null
+++ b/dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/error_test.go
@@ -0,0 +1,717 @@
+// Copyright (c) 2017-2021 Uber Technologies, Inc.
+//
+// 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 multierr
+
+import (
+ "errors"
+ "fmt"
+ "io"
+ "sync"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+// richFormatError is an error that prints a different output depending on
+// whether %v or %+v was used.
+type richFormatError struct{}
+
+func (r richFormatError) Error() string {
+ return fmt.Sprint(r)
+}
+
+func (richFormatError) Format(f fmt.State, c rune) {
+ if c == 'v' && f.Flag('+') {
+ io.WriteString(f, "multiline\nmessage\nwith plus")
+ } else {
+ io.WriteString(f, "without plus")
+ }
+}
+
+func appendN(initial, err error, n int) error {
+ errs := initial
+ for i := 0; i < n; i++ {
+ errs = Append(errs, err)
+ }
+ return errs
+}
+
+func newMultiErr(errors ...error) error {
+ return &multiError{errors: errors}
+}
+
+func TestCombine(t *testing.T) {
+ tests := []struct {
+ // Input
+ giveErrors []error
+
+ // Resulting error
+ wantError error
+
+ // %+v and %v string representations
+ wantMultiline string
+ wantSingleline string
+ }{
+ {
+ giveErrors: nil,
+ wantError: nil,
+ },
+ {
+ giveErrors: []error{},
+ wantError: nil,
+ },
+ {
+ giveErrors: []error{
+ errors.New("foo"),
+ nil,
+ newMultiErr(
+ errors.New("bar"),
+ ),
+ nil,
+ },
+ wantError: newMultiErr(
+ errors.New("foo"),
+ errors.New("bar"),
+ ),
+ wantMultiline: "the following errors occurred:\n" +
+ " - foo\n" +
+ " - bar",
+ wantSingleline: "foo; bar",
+ },
+ {
+ giveErrors: []error{nil, nil, errors.New("great sadness"), nil},
+ wantError: errors.New("great sadness"),
+ wantMultiline: "great sadness",
+ wantSingleline: "great sadness",
+ },
+ {
+ giveErrors: []error{
+ errors.New("foo"),
+ newMultiErr(
+ errors.New("bar"),
+ ),
+ },
+ wantError: newMultiErr(
+ errors.New("foo"),
+ errors.New("bar"),
+ ),
+ wantMultiline: "the following errors occurred:\n" +
+ " - foo\n" +
+ " - bar",
+ wantSingleline: "foo; bar",
+ },
+ {
+ giveErrors: []error{errors.New("great sadness")},
+ wantError: errors.New("great sadness"),
+ wantMultiline: "great sadness",
+ wantSingleline: "great sadness",
+ },
+ {
+ giveErrors: []error{
+ errors.New("foo"),
+ errors.New("bar"),
+ },
+ wantError: newMultiErr(
+ errors.New("foo"),
+ errors.New("bar"),
+ ),
+ wantMultiline: "the following errors occurred:\n" +
+ " - foo\n" +
+ " - bar",
+ wantSingleline: "foo; bar",
+ },
+ {
+ giveErrors: []error{
+ errors.New("great sadness"),
+ errors.New("multi\n line\nerror message"),
+ errors.New("single line error message"),
+ },
+ wantError: newMultiErr(
+ errors.New("great sadness"),
+ errors.New("multi\n line\nerror message"),
+ errors.New("single line error message"),
+ ),
+ wantMultiline: "the following errors occurred:\n" +
+ " - great sadness\n" +
+ " - multi\n" +
+ " line\n" +
+ " error message\n" +
+ " - single line error message",
+ wantSingleline: "great sadness; " +
+ "multi\n line\nerror message; " +
+ "single line error message",
+ },
+ {
+ giveErrors: []error{
+ errors.New("foo"),
+ newMultiErr(
+ errors.New("bar"),
+ errors.New("baz"),
+ ),
+ errors.New("qux"),
+ },
+ wantError: newMultiErr(
+ errors.New("foo"),
+ errors.New("bar"),
+ errors.New("baz"),
+ errors.New("qux"),
+ ),
+ wantMultiline: "the following errors occurred:\n" +
+ " - foo\n" +
+ " - bar\n" +
+ " - baz\n" +
+ " - qux",
+ wantSingleline: "foo; bar; baz; qux",
+ },
+ {
+ giveErrors: []error{
+ errors.New("foo"),
+ nil,
+ newMultiErr(
+ errors.New("bar"),
+ ),
+ nil,
+ },
+ wantError: newMultiErr(
+ errors.New("foo"),
+ errors.New("bar"),
+ ),
+ wantMultiline: "the following errors occurred:\n" +
+ " - foo\n" +
+ " - bar",
+ wantSingleline: "foo; bar",
+ },
+ {
+ giveErrors: []error{
+ errors.New("foo"),
+ newMultiErr(
+ errors.New("bar"),
+ ),
+ },
+ wantError: newMultiErr(
+ errors.New("foo"),
+ errors.New("bar"),
+ ),
+ wantMultiline: "the following errors occurred:\n" +
+ " - foo\n" +
+ " - bar",
+ wantSingleline: "foo; bar",
+ },
+ {
+ giveErrors: []error{
+ errors.New("foo"),
+ richFormatError{},
+ errors.New("bar"),
+ },
+ wantError: newMultiErr(
+ errors.New("foo"),
+ richFormatError{},
+ errors.New("bar"),
+ ),
+ wantMultiline: "the following errors occurred:\n" +
+ " - foo\n" +
+ " - multiline\n" +
+ " message\n" +
+ " with plus\n" +
+ " - bar",
+ wantSingleline: "foo; without plus; bar",
+ },
+ }
+
+ for i, tt := range tests {
+ t.Run(fmt.Sprint(i), func(t *testing.T) {
+ err := Combine(tt.giveErrors...)
+ require.Equal(t, tt.wantError, err)
+
+ if tt.wantMultiline != "" {
+ t.Run("Sprintf/multiline", func(t *testing.T) {
+ assert.Equal(t, tt.wantMultiline, fmt.Sprintf("%+v", err))
+ })
+ }
+
+ if tt.wantSingleline != "" {
+ t.Run("Sprintf/singleline", func(t *testing.T) {
+ assert.Equal(t, tt.wantSingleline, fmt.Sprintf("%v", err))
+ })
+
+ t.Run("Error()", func(t *testing.T) {
+ assert.Equal(t, tt.wantSingleline, err.Error())
+ })
+
+ if s, ok := err.(fmt.Stringer); ok {
+ t.Run("String()", func(t *testing.T) {
+ assert.Equal(t, tt.wantSingleline, s.String())
+ })
+ }
+ }
+ })
+ }
+}
+
+func TestCombineDoesNotModifySlice(t *testing.T) {
+ errors := []error{
+ errors.New("foo"),
+ nil,
+ errors.New("bar"),
+ }
+
+ assert.NotNil(t, Combine(errors...))
+ assert.Len(t, errors, 3)
+ assert.Nil(t, errors[1], 3)
+}
+
+func TestCombineGoodCaseNoAlloc(t *testing.T) {
+ errs := make([]error, 10)
+ allocs := testing.AllocsPerRun(100, func() {
+ Combine(errs...)
+ })
+ assert.Equal(t, 0.0, allocs)
+}
+
+func TestAppend(t *testing.T) {
+ tests := []struct {
+ left error
+ right error
+ want error
+ }{
+ {
+ left: nil,
+ right: nil,
+ want: nil,
+ },
+ {
+ left: nil,
+ right: errors.New("great sadness"),
+ want: errors.New("great sadness"),
+ },
+ {
+ left: errors.New("great sadness"),
+ right: nil,
+ want: errors.New("great sadness"),
+ },
+ {
+ left: errors.New("foo"),
+ right: errors.New("bar"),
+ want: newMultiErr(
+ errors.New("foo"),
+ errors.New("bar"),
+ ),
+ },
+ {
+ left: newMultiErr(
+ errors.New("foo"),
+ errors.New("bar"),
+ ),
+ right: errors.New("baz"),
+ want: newMultiErr(
+ errors.New("foo"),
+ errors.New("bar"),
+ errors.New("baz"),
+ ),
+ },
+ {
+ left: errors.New("baz"),
+ right: newMultiErr(
+ errors.New("foo"),
+ errors.New("bar"),
+ ),
+ want: newMultiErr(
+ errors.New("baz"),
+ errors.New("foo"),
+ errors.New("bar"),
+ ),
+ },
+ {
+ left: newMultiErr(
+ errors.New("foo"),
+ ),
+ right: newMultiErr(
+ errors.New("bar"),
+ ),
+ want: newMultiErr(
+ errors.New("foo"),
+ errors.New("bar"),
+ ),
+ },
+ }
+
+ for _, tt := range tests {
+ assert.Equal(t, tt.want, Append(tt.left, tt.right))
+ }
+}
+
+type notMultiErr struct{}
+
+var _ errorGroup = notMultiErr{}
+
+func (notMultiErr) Error() string {
+ return "great sadness"
+}
+
+func (notMultiErr) Errors() []error {
+ return []error{errors.New("great sadness")}
+}
+
+func TestErrors(t *testing.T) {
+ tests := []struct {
+ give error
+ want []error
+
+ // Don't attempt to cast to errorGroup or *multiError
+ dontCast bool
+ }{
+ {dontCast: true}, // nil
+ {
+ give: errors.New("hi"),
+ want: []error{errors.New("hi")},
+ dontCast: true,
+ },
+ {
+ // We don't yet support non-multierr errors.
+ give: notMultiErr{},
+ want: []error{notMultiErr{}},
+ dontCast: true,
+ },
+ {
+ give: Combine(
+ errors.New("foo"),
+ errors.New("bar"),
+ ),
+ want: []error{
+ errors.New("foo"),
+ errors.New("bar"),
+ },
+ },
+ {
+ give: Append(
+ errors.New("foo"),
+ errors.New("bar"),
+ ),
+ want: []error{
+ errors.New("foo"),
+ errors.New("bar"),
+ },
+ },
+ {
+ give: Append(
+ errors.New("foo"),
+ Combine(
+ errors.New("bar"),
+ ),
+ ),
+ want: []error{
+ errors.New("foo"),
+ errors.New("bar"),
+ },
+ },
+ {
+ give: Combine(
+ errors.New("foo"),
+ Append(
+ errors.New("bar"),
+ errors.New("baz"),
+ ),
+ errors.New("qux"),
+ ),
+ want: []error{
+ errors.New("foo"),
+ errors.New("bar"),
+ errors.New("baz"),
+ errors.New("qux"),
+ },
+ },
+ }
+
+ for i, tt := range tests {
+ t.Run(fmt.Sprint(i), func(t *testing.T) {
+ t.Run("Errors()", func(t *testing.T) {
+ require.Equal(t, tt.want, Errors(tt.give))
+ })
+
+ if tt.dontCast {
+ return
+ }
+
+ t.Run("multiError", func(t *testing.T) {
+ require.Equal(t, tt.want, tt.give.(*multiError).Errors())
+ })
+
+ t.Run("errorGroup", func(t *testing.T) {
+ require.Equal(t, tt.want, tt.give.(errorGroup).Errors())
+ })
+ })
+ }
+}
+
+func createMultiErrWithCapacity() error {
+ // Create a multiError that has capacity for more errors so Append will
+ // modify the underlying array that may be shared.
+ return appendN(nil, errors.New("append"), 50)
+}
+
+func TestAppendDoesNotModify(t *testing.T) {
+ initial := createMultiErrWithCapacity()
+ err1 := Append(initial, errors.New("err1"))
+ err2 := Append(initial, errors.New("err2"))
+
+ // Make sure the error messages match, since we do modify the copyNeeded
+ // atomic, the values cannot be compared.
+ assert.EqualError(t, initial, createMultiErrWithCapacity().Error(), "Initial should not be modified")
+
+ assert.EqualError(t, err1, Append(createMultiErrWithCapacity(), errors.New("err1")).Error())
+ assert.EqualError(t, err2, Append(createMultiErrWithCapacity(), errors.New("err2")).Error())
+}
+
+func TestAppendRace(t *testing.T) {
+ initial := createMultiErrWithCapacity()
+
+ var wg sync.WaitGroup
+ for i := 0; i < 10; i++ {
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+
+ err := initial
+ for j := 0; j < 10; j++ {
+ err = Append(err, errors.New("err"))
+ }
+ }()
+ }
+
+ wg.Wait()
+}
+
+func TestErrorsSliceIsImmutable(t *testing.T) {
+ err1 := errors.New("err1")
+ err2 := errors.New("err2")
+
+ err := Append(err1, err2)
+ gotErrors := Errors(err)
+ require.Equal(t, []error{err1, err2}, gotErrors, "errors must match")
+
+ gotErrors[0] = nil
+ gotErrors[1] = errors.New("err3")
+
+ require.Equal(t, []error{err1, err2}, Errors(err),
+ "errors must match after modification")
+}
+
+func TestNilMultierror(t *testing.T) {
+ // For safety, all operations on multiError should be safe even if it is
+ // nil.
+ var err *multiError
+
+ require.Empty(t, err.Error())
+ require.Empty(t, err.Errors())
+}
+
+func TestAppendInto(t *testing.T) {
+ tests := []struct {
+ desc string
+ into *error
+ give error
+ want error
+ }{
+ {
+ desc: "append into empty",
+ into: new(error),
+ give: errors.New("foo"),
+ want: errors.New("foo"),
+ },
+ {
+ desc: "append into non-empty, non-multierr",
+ into: errorPtr(errors.New("foo")),
+ give: errors.New("bar"),
+ want: Combine(
+ errors.New("foo"),
+ errors.New("bar"),
+ ),
+ },
+ {
+ desc: "append into non-empty multierr",
+ into: errorPtr(Combine(
+ errors.New("foo"),
+ errors.New("bar"),
+ )),
+ give: errors.New("baz"),
+ want: Combine(
+ errors.New("foo"),
+ errors.New("bar"),
+ errors.New("baz"),
+ ),
+ },
+ }
+
+ for _, tt := range tests {
+ t.Run(tt.desc, func(t *testing.T) {
+ assert.True(t, AppendInto(tt.into, tt.give))
+ assert.Equal(t, tt.want, *tt.into)
+ })
+ }
+}
+
+func TestAppendInvoke(t *testing.T) {
+ tests := []struct {
+ desc string
+ into *error
+ give Invoker
+ want error
+ }{
+ {
+ desc: "append into empty",
+ into: new(error),
+ give: Invoke(func() error {
+ return errors.New("foo")
+ }),
+ want: errors.New("foo"),
+ },
+ {
+ desc: "append into non-empty, non-multierr",
+ into: errorPtr(errors.New("foo")),
+ give: Invoke(func() error {
+ return errors.New("bar")
+ }),
+ want: Combine(
+ errors.New("foo"),
+ errors.New("bar"),
+ ),
+ },
+ {
+ desc: "append into non-empty multierr",
+ into: errorPtr(Combine(
+ errors.New("foo"),
+ errors.New("bar"),
+ )),
+ give: Invoke(func() error {
+ return errors.New("baz")
+ }),
+ want: Combine(
+ errors.New("foo"),
+ errors.New("bar"),
+ errors.New("baz"),
+ ),
+ },
+ {
+ desc: "close/empty",
+ into: new(error),
+ give: Close(newCloserMock(t, errors.New("foo"))),
+ want: errors.New("foo"),
+ },
+ {
+ desc: "close/no fail",
+ into: new(error),
+ give: Close(newCloserMock(t, nil)),
+ want: nil,
+ },
+ {
+ desc: "close/non-empty",
+ into: errorPtr(errors.New("foo")),
+ give: Close(newCloserMock(t, errors.New("bar"))),
+ want: Combine(
+ errors.New("foo"),
+ errors.New("bar"),
+ ),
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.desc, func(t *testing.T) {
+ AppendInvoke(tt.into, tt.give)
+ assert.Equal(t, tt.want, *tt.into)
+ })
+ }
+}
+
+func TestClose(t *testing.T) {
+ t.Run("fail", func(t *testing.T) {
+ give := errors.New("great sadness")
+ got := Close(newCloserMock(t, give)).Invoke()
+ assert.Same(t, give, got)
+ })
+
+ t.Run("success", func(t *testing.T) {
+ got := Close(newCloserMock(t, nil)).Invoke()
+ assert.Nil(t, got)
+ })
+}
+
+func TestAppendIntoNil(t *testing.T) {
+ t.Run("nil pointer panics", func(t *testing.T) {
+ assert.Panics(t, func() {
+ AppendInto(nil, errors.New("foo"))
+ })
+ })
+
+ t.Run("nil error is no-op", func(t *testing.T) {
+ t.Run("empty left", func(t *testing.T) {
+ var err error
+ assert.False(t, AppendInto(&err, nil))
+ assert.Nil(t, err)
+ })
+
+ t.Run("non-empty left", func(t *testing.T) {
+ err := errors.New("foo")
+ assert.False(t, AppendInto(&err, nil))
+ assert.Equal(t, errors.New("foo"), err)
+ })
+ })
+}
+
+func TestAppendFunc(t *testing.T) {
+ var (
+ errDeferred = errors.New("deferred func called")
+ errOriginal = errors.New("original error")
+ )
+
+ stopFunc := func() error {
+ return errDeferred
+ }
+
+ err := func() (err error) {
+ defer AppendFunc(&err, stopFunc)
+
+ return errOriginal
+ }()
+ assert.Equal(t, []error{errOriginal, errDeferred}, Errors(err), "both deferred and original error must be returned")
+}
+
+func errorPtr(err error) *error {
+ return &err
+}
+
+type closerMock func() error
+
+func (c closerMock) Close() error {
+ return c()
+}
+
+func newCloserMock(tb testing.TB, err error) io.Closer {
+ var closed bool
+ tb.Cleanup(func() {
+ if !closed {
+ tb.Error("closerMock wasn't closed before test end")
+ }
+ })
+ return closerMock(func() error {
+ closed = true
+ return err
+ })
+}
diff --git a/dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/example_test.go b/dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/example_test.go
new file mode 100644
index 0000000..e46a633
--- /dev/null
+++ b/dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/example_test.go
@@ -0,0 +1,124 @@
+// Copyright (c) 2017-2021 Uber Technologies, Inc.
+//
+// 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 multierr_test
+
+import (
+ "errors"
+ "fmt"
+ "io"
+
+ "go.uber.org/multierr"
+)
+
+func ExampleCombine() {
+ err := multierr.Combine(
+ errors.New("call 1 failed"),
+ nil, // successful request
+ errors.New("call 3 failed"),
+ nil, // successful request
+ errors.New("call 5 failed"),
+ )
+ fmt.Printf("%+v", err)
+ // Output:
+ // the following errors occurred:
+ // - call 1 failed
+ // - call 3 failed
+ // - call 5 failed
+}
+
+func ExampleAppend() {
+ var err error
+ err = multierr.Append(err, errors.New("call 1 failed"))
+ err = multierr.Append(err, errors.New("call 2 failed"))
+ fmt.Println(err)
+ // Output:
+ // call 1 failed; call 2 failed
+}
+
+func ExampleErrors() {
+ err := multierr.Combine(
+ nil, // successful request
+ errors.New("call 2 failed"),
+ errors.New("call 3 failed"),
+ )
+ err = multierr.Append(err, nil) // successful request
+ err = multierr.Append(err, errors.New("call 5 failed"))
+
+ errors := multierr.Errors(err)
+ for _, err := range errors {
+ fmt.Println(err)
+ }
+ // Output:
+ // call 2 failed
+ // call 3 failed
+ // call 5 failed
+}
+
+func ExampleAppendInto() {
+ var err error
+
+ if multierr.AppendInto(&err, errors.New("foo")) {
+ fmt.Println("call 1 failed")
+ }
+
+ if multierr.AppendInto(&err, nil) {
+ fmt.Println("call 2 failed")
+ }
+
+ if multierr.AppendInto(&err, errors.New("baz")) {
+ fmt.Println("call 3 failed")
+ }
+
+ fmt.Println(err)
+ // Output:
+ // call 1 failed
+ // call 3 failed
+ // foo; baz
+}
+
+type fakeCloser func() error
+
+func (f fakeCloser) Close() error {
+ return f()
+}
+
+func FakeCloser(err error) io.Closer {
+ return fakeCloser(func() error {
+ return err
+ })
+}
+
+func ExampleClose() {
+ var err error
+
+ closer := FakeCloser(errors.New("foo"))
+
+ defer func() {
+ fmt.Println(err)
+ }()
+ defer multierr.AppendInvoke(&err, multierr.Close(closer))
+
+ fmt.Println("Hello, World")
+
+ // Output:
+ // Hello, World
+ // foo
+}
diff --git a/dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/go.mod b/dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/go.mod
new file mode 100644
index 0000000..1b4e0f5
--- /dev/null
+++ b/dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/go.mod
@@ -0,0 +1,11 @@
+module go.uber.org/multierr
+
+go 1.19
+
+require github.com/stretchr/testify v1.7.0
+
+require (
+ github.com/davecgh/go-spew v1.1.1 // indirect
+ github.com/pmezard/go-difflib v1.0.0 // indirect
+ gopkg.in/yaml.v3 v3.0.1 // indirect
+)
diff --git a/dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/go.sum b/dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/go.sum
new file mode 100644
index 0000000..e43413c
--- /dev/null
+++ b/dependencies/pkg/mod/go.uber.org/multierr@v1.10.0/go.sum
@@ -0,0 +1,13 @@
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
+github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
+github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=