summaryrefslogtreecommitdiffstats
path: root/dependencies/pkg/mod/go.uber.org/multierr@v1.6.0
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--dependencies/pkg/mod/go.uber.org/multierr@v1.6.0/.codecov.yml15
-rw-r--r--dependencies/pkg/mod/go.uber.org/multierr@v1.6.0/.gitignore4
-rw-r--r--dependencies/pkg/mod/go.uber.org/multierr@v1.6.0/.travis.yml23
-rw-r--r--dependencies/pkg/mod/go.uber.org/multierr@v1.6.0/CHANGELOG.md60
-rw-r--r--dependencies/pkg/mod/go.uber.org/multierr@v1.6.0/LICENSE.txt19
-rw-r--r--dependencies/pkg/mod/go.uber.org/multierr@v1.6.0/Makefile42
-rw-r--r--dependencies/pkg/mod/go.uber.org/multierr@v1.6.0/README.md23
-rw-r--r--dependencies/pkg/mod/go.uber.org/multierr@v1.6.0/benchmarks_test.go62
-rw-r--r--dependencies/pkg/mod/go.uber.org/multierr@v1.6.0/error.go449
-rw-r--r--dependencies/pkg/mod/go.uber.org/multierr@v1.6.0/error_test.go582
-rw-r--r--dependencies/pkg/mod/go.uber.org/multierr@v1.6.0/example_test.go94
-rw-r--r--dependencies/pkg/mod/go.uber.org/multierr@v1.6.0/glide.yaml8
-rw-r--r--dependencies/pkg/mod/go.uber.org/multierr@v1.6.0/go.mod8
-rw-r--r--dependencies/pkg/mod/go.uber.org/multierr@v1.6.0/go.sum11
-rw-r--r--dependencies/pkg/mod/go.uber.org/multierr@v1.6.0/go113.go52
-rw-r--r--dependencies/pkg/mod/go.uber.org/multierr@v1.6.0/go113_test.go144
16 files changed, 1596 insertions, 0 deletions
diff --git a/dependencies/pkg/mod/go.uber.org/multierr@v1.6.0/.codecov.yml b/dependencies/pkg/mod/go.uber.org/multierr@v1.6.0/.codecov.yml
new file mode 100644
index 0000000..6d4d1be
--- /dev/null
+++ b/dependencies/pkg/mod/go.uber.org/multierr@v1.6.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.6.0/.gitignore b/dependencies/pkg/mod/go.uber.org/multierr@v1.6.0/.gitignore
new file mode 100644
index 0000000..b9a05e3
--- /dev/null
+++ b/dependencies/pkg/mod/go.uber.org/multierr@v1.6.0/.gitignore
@@ -0,0 +1,4 @@
+/vendor
+cover.html
+cover.out
+/bin
diff --git a/dependencies/pkg/mod/go.uber.org/multierr@v1.6.0/.travis.yml b/dependencies/pkg/mod/go.uber.org/multierr@v1.6.0/.travis.yml
new file mode 100644
index 0000000..8636ab4
--- /dev/null
+++ b/dependencies/pkg/mod/go.uber.org/multierr@v1.6.0/.travis.yml
@@ -0,0 +1,23 @@
+sudo: false
+language: go
+go_import_path: go.uber.org/multierr
+
+env:
+ global:
+ - GO111MODULE=on
+
+go:
+ - oldstable
+ - stable
+
+before_install:
+- go version
+
+script:
+- |
+ set -e
+ make lint
+ make cover
+
+after_success:
+- bash <(curl -s https://codecov.io/bash)
diff --git a/dependencies/pkg/mod/go.uber.org/multierr@v1.6.0/CHANGELOG.md b/dependencies/pkg/mod/go.uber.org/multierr@v1.6.0/CHANGELOG.md
new file mode 100644
index 0000000..6f1db9e
--- /dev/null
+++ b/dependencies/pkg/mod/go.uber.org/multierr@v1.6.0/CHANGELOG.md
@@ -0,0 +1,60 @@
+Releases
+========
+
+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.6.0/LICENSE.txt b/dependencies/pkg/mod/go.uber.org/multierr@v1.6.0/LICENSE.txt
new file mode 100644
index 0000000..858e024
--- /dev/null
+++ b/dependencies/pkg/mod/go.uber.org/multierr@v1.6.0/LICENSE.txt
@@ -0,0 +1,19 @@
+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.
diff --git a/dependencies/pkg/mod/go.uber.org/multierr@v1.6.0/Makefile b/dependencies/pkg/mod/go.uber.org/multierr@v1.6.0/Makefile
new file mode 100644
index 0000000..3160044
--- /dev/null
+++ b/dependencies/pkg/mod/go.uber.org/multierr@v1.6.0/Makefile
@@ -0,0 +1,42 @@
+# 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 -coverprofile=cover.out -coverpkg=./... -v ./...
+ go tool cover -html=cover.out -o cover.html
+
+update-license:
+ @cd tools && go install go.uber.org/tools/update-license
+ @$(GOBIN)/update-license $(GO_FILES)
diff --git a/dependencies/pkg/mod/go.uber.org/multierr@v1.6.0/README.md b/dependencies/pkg/mod/go.uber.org/multierr@v1.6.0/README.md
new file mode 100644
index 0000000..751bd65
--- /dev/null
+++ b/dependencies/pkg/mod/go.uber.org/multierr@v1.6.0/README.md
@@ -0,0 +1,23 @@
+# 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.
+
+## Installation
+
+ go get -u go.uber.org/multierr
+
+## Status
+
+Stable: No breaking changes will be made before 2.0.
+
+-------------------------------------------------------------------------------
+
+Released under the [MIT License].
+
+[MIT License]: LICENSE.txt
+[doc-img]: https://godoc.org/go.uber.org/multierr?status.svg
+[doc]: https://godoc.org/go.uber.org/multierr
+[ci-img]: https://travis-ci.com/uber-go/multierr.svg?branch=master
+[cov-img]: https://codecov.io/gh/uber-go/multierr/branch/master/graph/badge.svg
+[ci]: https://travis-ci.com/uber-go/multierr
+[cov]: https://codecov.io/gh/uber-go/multierr
diff --git a/dependencies/pkg/mod/go.uber.org/multierr@v1.6.0/benchmarks_test.go b/dependencies/pkg/mod/go.uber.org/multierr@v1.6.0/benchmarks_test.go
new file mode 100644
index 0000000..797f5a0
--- /dev/null
+++ b/dependencies/pkg/mod/go.uber.org/multierr@v1.6.0/benchmarks_test.go
@@ -0,0 +1,62 @@
+// 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)
+ }
+ })
+ }
+ })
+ }
+ }
+}
diff --git a/dependencies/pkg/mod/go.uber.org/multierr@v1.6.0/error.go b/dependencies/pkg/mod/go.uber.org/multierr@v1.6.0/error.go
new file mode 100644
index 0000000..5c9b67d
--- /dev/null
+++ b/dependencies/pkg/mod/go.uber.org/multierr@v1.6.0/error.go
@@ -0,0 +1,449 @@
+// Copyright (c) 2019 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())
+//
+// This makes it possible to record resource cleanup failures from deferred
+// blocks with the help of named return values.
+//
+// func sendRequest(req Request) (err error) {
+// conn, err := openConnection()
+// if err != nil {
+// return err
+// }
+// defer func() {
+// err = multierr.Append(err, conn.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)
+// }
+//
+// 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"
+
+ "go.uber.org/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}
+ }
+
+ errors := eg.Errors()
+ result := make([]error, len(errors))
+ copy(result, errors)
+ return result
+}
+
+// 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 {
+ 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 {
+ // already flat
+ return &multiError{errors: errors}
+ }
+ }
+
+ 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())
+// }()
+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 verison 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
+}
diff --git a/dependencies/pkg/mod/go.uber.org/multierr@v1.6.0/error_test.go b/dependencies/pkg/mod/go.uber.org/multierr@v1.6.0/error_test.go
new file mode 100644
index 0000000..96c869e
--- /dev/null
+++ b/dependencies/pkg/mod/go.uber.org/multierr@v1.6.0/error_test.go
@@ -0,0 +1,582 @@
+// Copyright (c) 2019 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{
+ 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 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 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 errorPtr(err error) *error {
+ return &err
+}
diff --git a/dependencies/pkg/mod/go.uber.org/multierr@v1.6.0/example_test.go b/dependencies/pkg/mod/go.uber.org/multierr@v1.6.0/example_test.go
new file mode 100644
index 0000000..ad7b802
--- /dev/null
+++ b/dependencies/pkg/mod/go.uber.org/multierr@v1.6.0/example_test.go
@@ -0,0 +1,94 @@
+// 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_test
+
+import (
+ "errors"
+ "fmt"
+
+ "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
+}
diff --git a/dependencies/pkg/mod/go.uber.org/multierr@v1.6.0/glide.yaml b/dependencies/pkg/mod/go.uber.org/multierr@v1.6.0/glide.yaml
new file mode 100644
index 0000000..6ef084e
--- /dev/null
+++ b/dependencies/pkg/mod/go.uber.org/multierr@v1.6.0/glide.yaml
@@ -0,0 +1,8 @@
+package: go.uber.org/multierr
+import:
+- package: go.uber.org/atomic
+ version: ^1
+testImport:
+- package: github.com/stretchr/testify
+ subpackages:
+ - assert
diff --git a/dependencies/pkg/mod/go.uber.org/multierr@v1.6.0/go.mod b/dependencies/pkg/mod/go.uber.org/multierr@v1.6.0/go.mod
new file mode 100644
index 0000000..ff8bdf9
--- /dev/null
+++ b/dependencies/pkg/mod/go.uber.org/multierr@v1.6.0/go.mod
@@ -0,0 +1,8 @@
+module go.uber.org/multierr
+
+go 1.12
+
+require (
+ github.com/stretchr/testify v1.3.0
+ go.uber.org/atomic v1.7.0
+)
diff --git a/dependencies/pkg/mod/go.uber.org/multierr@v1.6.0/go.sum b/dependencies/pkg/mod/go.uber.org/multierr@v1.6.0/go.sum
new file mode 100644
index 0000000..ecfc286
--- /dev/null
+++ b/dependencies/pkg/mod/go.uber.org/multierr@v1.6.0/go.sum
@@ -0,0 +1,11 @@
+github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
+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.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
+github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
+go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
+go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
diff --git a/dependencies/pkg/mod/go.uber.org/multierr@v1.6.0/go113.go b/dependencies/pkg/mod/go.uber.org/multierr@v1.6.0/go113.go
new file mode 100644
index 0000000..264b0ea
--- /dev/null
+++ b/dependencies/pkg/mod/go.uber.org/multierr@v1.6.0/go113.go
@@ -0,0 +1,52 @@
+// Copyright (c) 2019 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.
+
+// +build go1.13
+
+package multierr
+
+import "errors"
+
+// 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.6.0/go113_test.go b/dependencies/pkg/mod/go.uber.org/multierr@v1.6.0/go113_test.go
new file mode 100644
index 0000000..4fbd0bb
--- /dev/null
+++ b/dependencies/pkg/mod/go.uber.org/multierr@v1.6.0/go113_test.go
@@ -0,0 +1,144 @@
+// Copyright (c) 2019 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.
+
+// +build go1.13
+
+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}))
+ })
+}