squash merge from dev branch
This commit is contained in:
8
vendor/go.uber.org/atomic/.github/PULL_REQUEST_TEMPLATE.md
generated
vendored
Normal file
8
vendor/go.uber.org/atomic/.github/PULL_REQUEST_TEMPLATE.md
generated
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
Before opening your pull request, please make sure that you've:
|
||||
|
||||
- [ ] [signed Uber's Contributor License Agreement](https://docs.google.com/a/uber.com/forms/d/1pAwS_-dA1KhPlfxzYLBqK6rsSWwRwH95OCCZrcsY5rk/viewform);
|
||||
- [ ] added tests to cover your changes;
|
||||
- [ ] run the test suite locally (`make test`); and finally,
|
||||
- [ ] run the linters locally (`make lint`).
|
||||
|
||||
Thanks for your contribution!
|
||||
21
vendor/go.uber.org/atomic/.travis.yml
generated
vendored
Normal file
21
vendor/go.uber.org/atomic/.travis.yml
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
sudo: false
|
||||
language: go
|
||||
go_import_path: go.uber.org/atomic
|
||||
|
||||
go:
|
||||
- 1.5
|
||||
- 1.6
|
||||
- tip
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- vendor
|
||||
|
||||
install:
|
||||
- make install_ci
|
||||
|
||||
script:
|
||||
- make test_ci
|
||||
- scripts/test-ubergo.sh
|
||||
- make lint
|
||||
- travis_retry goveralls -coverprofile=cover.out -service=travis-ci
|
||||
19
vendor/go.uber.org/atomic/LICENSE.txt
generated
vendored
Normal file
19
vendor/go.uber.org/atomic/LICENSE.txt
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
Copyright (c) 2016 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.
|
||||
64
vendor/go.uber.org/atomic/Makefile
generated
vendored
Normal file
64
vendor/go.uber.org/atomic/Makefile
generated
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
PACKAGES := $(shell glide nv)
|
||||
# Many Go tools take file globs or directories as arguments instead of packages.
|
||||
PACKAGE_FILES ?= *.go
|
||||
|
||||
|
||||
# The linting tools evolve with each Go version, so run them only on the latest
|
||||
# stable release.
|
||||
GO_VERSION := $(shell go version | cut -d " " -f 3)
|
||||
GO_MINOR_VERSION := $(word 2,$(subst ., ,$(GO_VERSION)))
|
||||
LINTABLE_MINOR_VERSIONS := 7 8
|
||||
ifneq ($(filter $(LINTABLE_MINOR_VERSIONS),$(GO_MINOR_VERSION)),)
|
||||
SHOULD_LINT := true
|
||||
endif
|
||||
|
||||
|
||||
export GO15VENDOREXPERIMENT=1
|
||||
|
||||
|
||||
.PHONY: build
|
||||
build:
|
||||
go build -i $(PACKAGES)
|
||||
|
||||
|
||||
.PHONY: install
|
||||
install:
|
||||
glide --version || go get github.com/Masterminds/glide
|
||||
glide install
|
||||
|
||||
|
||||
.PHONY: test
|
||||
test:
|
||||
go test -cover -race $(PACKAGES)
|
||||
|
||||
|
||||
.PHONY: install_ci
|
||||
install_ci: install
|
||||
go get github.com/wadey/gocovmerge
|
||||
go get github.com/mattn/goveralls
|
||||
go get golang.org/x/tools/cmd/cover
|
||||
ifdef SHOULD_LINT
|
||||
go get github.com/golang/lint/golint
|
||||
endif
|
||||
|
||||
.PHONY: lint
|
||||
lint:
|
||||
ifdef SHOULD_LINT
|
||||
@rm -rf lint.log
|
||||
@echo "Checking formatting..."
|
||||
@gofmt -d -s $(PACKAGE_FILES) 2>&1 | tee lint.log
|
||||
@echo "Checking vet..."
|
||||
@$(foreach dir,$(PACKAGE_FILES),go tool vet $(dir) 2>&1 | tee -a lint.log;)
|
||||
@echo "Checking lint..."
|
||||
@$(foreach dir,$(PKGS),golint $(dir) 2>&1 | tee -a lint.log;)
|
||||
@echo "Checking for unresolved FIXMEs..."
|
||||
@git grep -i fixme | grep -v -e vendor -e Makefile | tee -a lint.log
|
||||
@[ ! -s lint.log ]
|
||||
else
|
||||
@echo "Skipping linters on" $(GO_VERSION)
|
||||
endif
|
||||
|
||||
|
||||
.PHONY: test_ci
|
||||
test_ci: install_ci build
|
||||
./scripts/cover.sh $(shell go list $(PACKAGES))
|
||||
34
vendor/go.uber.org/atomic/README.md
generated
vendored
Normal file
34
vendor/go.uber.org/atomic/README.md
generated
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
# atomic [![GoDoc][doc-img]][doc] [![Build Status][ci-img]][ci] [![Coverage Status][cov-img]][cov]
|
||||
|
||||
Simple wrappers for primitive types to enforce atomic access.
|
||||
|
||||
## Installation
|
||||
`go get -u go.uber.org/atomic`
|
||||
|
||||
## Usage
|
||||
The standard library's `sync/atomic` is powerful, but it's easy to forget which
|
||||
variables must be accessed atomically. `go.uber.org/atomic` preserves all the
|
||||
functionality of the standard library, but wraps the primitive types to
|
||||
provide a safer, more convenient API.
|
||||
|
||||
```go
|
||||
var atom atomic.Uint32
|
||||
atom.Store(42)
|
||||
atom.Sub(2)
|
||||
atom.CAS(40, 11)
|
||||
```
|
||||
|
||||
See the [documentation][doc] for a complete API specification.
|
||||
|
||||
## Development Status
|
||||
Stable.
|
||||
|
||||
<hr>
|
||||
Released under the [MIT License](LICENSE.txt).
|
||||
|
||||
[doc-img]: https://godoc.org/github.com/uber-go/atomic?status.svg
|
||||
[doc]: https://godoc.org/go.uber.org/atomic
|
||||
[ci-img]: https://travis-ci.org/uber-go/atomic.svg?branch=master
|
||||
[ci]: https://travis-ci.org/uber-go/atomic
|
||||
[cov-img]: https://coveralls.io/repos/github/uber-go/atomic/badge.svg?branch=master
|
||||
[cov]: https://coveralls.io/github/uber-go/atomic?branch=master
|
||||
304
vendor/go.uber.org/atomic/atomic.go
generated
vendored
Normal file
304
vendor/go.uber.org/atomic/atomic.go
generated
vendored
Normal file
@@ -0,0 +1,304 @@
|
||||
// Copyright (c) 2016 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 atomic provides simple wrappers around numerics to enforce atomic
|
||||
// access.
|
||||
package atomic
|
||||
|
||||
import (
|
||||
"math"
|
||||
"sync/atomic"
|
||||
)
|
||||
|
||||
// Int32 is an atomic wrapper around an int32.
|
||||
type Int32 struct{ v int32 }
|
||||
|
||||
// NewInt32 creates an Int32.
|
||||
func NewInt32(i int32) *Int32 {
|
||||
return &Int32{i}
|
||||
}
|
||||
|
||||
// Load atomically loads the wrapped value.
|
||||
func (i *Int32) Load() int32 {
|
||||
return atomic.LoadInt32(&i.v)
|
||||
}
|
||||
|
||||
// Add atomically adds to the wrapped int32 and returns the new value.
|
||||
func (i *Int32) Add(n int32) int32 {
|
||||
return atomic.AddInt32(&i.v, n)
|
||||
}
|
||||
|
||||
// Sub atomically subtracts from the wrapped int32 and returns the new value.
|
||||
func (i *Int32) Sub(n int32) int32 {
|
||||
return atomic.AddInt32(&i.v, -n)
|
||||
}
|
||||
|
||||
// Inc atomically increments the wrapped int32 and returns the new value.
|
||||
func (i *Int32) Inc() int32 {
|
||||
return i.Add(1)
|
||||
}
|
||||
|
||||
// Dec atomically decrements the wrapped int32 and returns the new value.
|
||||
func (i *Int32) Dec() int32 {
|
||||
return i.Sub(1)
|
||||
}
|
||||
|
||||
// CAS is an atomic compare-and-swap.
|
||||
func (i *Int32) CAS(old, new int32) bool {
|
||||
return atomic.CompareAndSwapInt32(&i.v, old, new)
|
||||
}
|
||||
|
||||
// Store atomically stores the passed value.
|
||||
func (i *Int32) Store(n int32) {
|
||||
atomic.StoreInt32(&i.v, n)
|
||||
}
|
||||
|
||||
// Swap atomically swaps the wrapped int32 and returns the old value.
|
||||
func (i *Int32) Swap(n int32) int32 {
|
||||
return atomic.SwapInt32(&i.v, n)
|
||||
}
|
||||
|
||||
// Int64 is an atomic wrapper around an int64.
|
||||
type Int64 struct{ v int64 }
|
||||
|
||||
// NewInt64 creates an Int64.
|
||||
func NewInt64(i int64) *Int64 {
|
||||
return &Int64{i}
|
||||
}
|
||||
|
||||
// Load atomically loads the wrapped value.
|
||||
func (i *Int64) Load() int64 {
|
||||
return atomic.LoadInt64(&i.v)
|
||||
}
|
||||
|
||||
// Add atomically adds to the wrapped int64 and returns the new value.
|
||||
func (i *Int64) Add(n int64) int64 {
|
||||
return atomic.AddInt64(&i.v, n)
|
||||
}
|
||||
|
||||
// Sub atomically subtracts from the wrapped int64 and returns the new value.
|
||||
func (i *Int64) Sub(n int64) int64 {
|
||||
return atomic.AddInt64(&i.v, -n)
|
||||
}
|
||||
|
||||
// Inc atomically increments the wrapped int64 and returns the new value.
|
||||
func (i *Int64) Inc() int64 {
|
||||
return i.Add(1)
|
||||
}
|
||||
|
||||
// Dec atomically decrements the wrapped int64 and returns the new value.
|
||||
func (i *Int64) Dec() int64 {
|
||||
return i.Sub(1)
|
||||
}
|
||||
|
||||
// CAS is an atomic compare-and-swap.
|
||||
func (i *Int64) CAS(old, new int64) bool {
|
||||
return atomic.CompareAndSwapInt64(&i.v, old, new)
|
||||
}
|
||||
|
||||
// Store atomically stores the passed value.
|
||||
func (i *Int64) Store(n int64) {
|
||||
atomic.StoreInt64(&i.v, n)
|
||||
}
|
||||
|
||||
// Swap atomically swaps the wrapped int64 and returns the old value.
|
||||
func (i *Int64) Swap(n int64) int64 {
|
||||
return atomic.SwapInt64(&i.v, n)
|
||||
}
|
||||
|
||||
// Uint32 is an atomic wrapper around an uint32.
|
||||
type Uint32 struct{ v uint32 }
|
||||
|
||||
// NewUint32 creates a Uint32.
|
||||
func NewUint32(i uint32) *Uint32 {
|
||||
return &Uint32{i}
|
||||
}
|
||||
|
||||
// Load atomically loads the wrapped value.
|
||||
func (i *Uint32) Load() uint32 {
|
||||
return atomic.LoadUint32(&i.v)
|
||||
}
|
||||
|
||||
// Add atomically adds to the wrapped uint32 and returns the new value.
|
||||
func (i *Uint32) Add(n uint32) uint32 {
|
||||
return atomic.AddUint32(&i.v, n)
|
||||
}
|
||||
|
||||
// Sub atomically subtracts from the wrapped uint32 and returns the new value.
|
||||
func (i *Uint32) Sub(n uint32) uint32 {
|
||||
return atomic.AddUint32(&i.v, ^(n - 1))
|
||||
}
|
||||
|
||||
// Inc atomically increments the wrapped uint32 and returns the new value.
|
||||
func (i *Uint32) Inc() uint32 {
|
||||
return i.Add(1)
|
||||
}
|
||||
|
||||
// Dec atomically decrements the wrapped int32 and returns the new value.
|
||||
func (i *Uint32) Dec() uint32 {
|
||||
return i.Sub(1)
|
||||
}
|
||||
|
||||
// CAS is an atomic compare-and-swap.
|
||||
func (i *Uint32) CAS(old, new uint32) bool {
|
||||
return atomic.CompareAndSwapUint32(&i.v, old, new)
|
||||
}
|
||||
|
||||
// Store atomically stores the passed value.
|
||||
func (i *Uint32) Store(n uint32) {
|
||||
atomic.StoreUint32(&i.v, n)
|
||||
}
|
||||
|
||||
// Swap atomically swaps the wrapped uint32 and returns the old value.
|
||||
func (i *Uint32) Swap(n uint32) uint32 {
|
||||
return atomic.SwapUint32(&i.v, n)
|
||||
}
|
||||
|
||||
// Uint64 is an atomic wrapper around a uint64.
|
||||
type Uint64 struct{ v uint64 }
|
||||
|
||||
// NewUint64 creates a Uint64.
|
||||
func NewUint64(i uint64) *Uint64 {
|
||||
return &Uint64{i}
|
||||
}
|
||||
|
||||
// Load atomically loads the wrapped value.
|
||||
func (i *Uint64) Load() uint64 {
|
||||
return atomic.LoadUint64(&i.v)
|
||||
}
|
||||
|
||||
// Add atomically adds to the wrapped uint64 and returns the new value.
|
||||
func (i *Uint64) Add(n uint64) uint64 {
|
||||
return atomic.AddUint64(&i.v, n)
|
||||
}
|
||||
|
||||
// Sub atomically subtracts from the wrapped uint64 and returns the new value.
|
||||
func (i *Uint64) Sub(n uint64) uint64 {
|
||||
return atomic.AddUint64(&i.v, ^(n - 1))
|
||||
}
|
||||
|
||||
// Inc atomically increments the wrapped uint64 and returns the new value.
|
||||
func (i *Uint64) Inc() uint64 {
|
||||
return i.Add(1)
|
||||
}
|
||||
|
||||
// Dec atomically decrements the wrapped uint64 and returns the new value.
|
||||
func (i *Uint64) Dec() uint64 {
|
||||
return i.Sub(1)
|
||||
}
|
||||
|
||||
// CAS is an atomic compare-and-swap.
|
||||
func (i *Uint64) CAS(old, new uint64) bool {
|
||||
return atomic.CompareAndSwapUint64(&i.v, old, new)
|
||||
}
|
||||
|
||||
// Store atomically stores the passed value.
|
||||
func (i *Uint64) Store(n uint64) {
|
||||
atomic.StoreUint64(&i.v, n)
|
||||
}
|
||||
|
||||
// Swap atomically swaps the wrapped uint64 and returns the old value.
|
||||
func (i *Uint64) Swap(n uint64) uint64 {
|
||||
return atomic.SwapUint64(&i.v, n)
|
||||
}
|
||||
|
||||
// Bool is an atomic Boolean.
|
||||
type Bool struct{ v uint32 }
|
||||
|
||||
// NewBool creates a Bool.
|
||||
func NewBool(initial bool) *Bool {
|
||||
return &Bool{boolToInt(initial)}
|
||||
}
|
||||
|
||||
// Load atomically loads the Boolean.
|
||||
func (b *Bool) Load() bool {
|
||||
return truthy(atomic.LoadUint32(&b.v))
|
||||
}
|
||||
|
||||
// Store atomically stores the passed value.
|
||||
func (b *Bool) Store(new bool) {
|
||||
atomic.StoreUint32(&b.v, boolToInt(new))
|
||||
}
|
||||
|
||||
// Swap sets the given value and returns the previous value.
|
||||
func (b *Bool) Swap(new bool) bool {
|
||||
return truthy(atomic.SwapUint32(&b.v, boolToInt(new)))
|
||||
}
|
||||
|
||||
// Toggle atomically negates the Boolean and returns the previous value.
|
||||
func (b *Bool) Toggle() bool {
|
||||
return truthy(atomic.AddUint32(&b.v, 1) - 1)
|
||||
}
|
||||
|
||||
func truthy(n uint32) bool {
|
||||
return n&1 == 1
|
||||
}
|
||||
|
||||
func boolToInt(b bool) uint32 {
|
||||
if b {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
// Float64 is an atomic wrapper around float64.
|
||||
type Float64 struct {
|
||||
v uint64
|
||||
}
|
||||
|
||||
// NewFloat64 creates a Float64.
|
||||
func NewFloat64(f float64) *Float64 {
|
||||
return &Float64{math.Float64bits(f)}
|
||||
}
|
||||
|
||||
// Load atomically loads the wrapped value.
|
||||
func (f *Float64) Load() float64 {
|
||||
return math.Float64frombits(atomic.LoadUint64(&f.v))
|
||||
}
|
||||
|
||||
// Store atomically stores the passed value.
|
||||
func (f *Float64) Store(s float64) {
|
||||
atomic.StoreUint64(&f.v, math.Float64bits(s))
|
||||
}
|
||||
|
||||
// Add atomically adds to the wrapped float64 and returns the new value.
|
||||
func (f *Float64) Add(s float64) float64 {
|
||||
for {
|
||||
old := f.Load()
|
||||
new := old + s
|
||||
if f.CAS(old, new) {
|
||||
return new
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sub atomically subtracts from the wrapped float64 and returns the new value.
|
||||
func (f *Float64) Sub(s float64) float64 {
|
||||
return f.Add(-s)
|
||||
}
|
||||
|
||||
// CAS is an atomic compare-and-swap.
|
||||
func (f *Float64) CAS(old, new float64) bool {
|
||||
return atomic.CompareAndSwapUint64(&f.v, math.Float64bits(old), math.Float64bits(new))
|
||||
}
|
||||
|
||||
// Value shadows the type of the same name from sync/atomic
|
||||
// https://godoc.org/sync/atomic#Value
|
||||
type Value struct{ atomic.Value }
|
||||
147
vendor/go.uber.org/atomic/atomic_test.go
generated
vendored
Normal file
147
vendor/go.uber.org/atomic/atomic_test.go
generated
vendored
Normal file
@@ -0,0 +1,147 @@
|
||||
// Copyright (c) 2016 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 atomic
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestInt32(t *testing.T) {
|
||||
atom := NewInt32(42)
|
||||
|
||||
require.Equal(t, int32(42), atom.Load(), "Load didn't work.")
|
||||
require.Equal(t, int32(46), atom.Add(4), "Add didn't work.")
|
||||
require.Equal(t, int32(44), atom.Sub(2), "Sub didn't work.")
|
||||
require.Equal(t, int32(45), atom.Inc(), "Inc didn't work.")
|
||||
require.Equal(t, int32(44), atom.Dec(), "Dec didn't work.")
|
||||
|
||||
require.True(t, atom.CAS(44, 0), "CAS didn't report a swap.")
|
||||
require.Equal(t, int32(0), atom.Load(), "CAS didn't set the correct value.")
|
||||
|
||||
require.Equal(t, int32(0), atom.Swap(1), "Swap didn't return the old value.")
|
||||
require.Equal(t, int32(1), atom.Load(), "Swap didn't set the correct value.")
|
||||
|
||||
atom.Store(42)
|
||||
require.Equal(t, int32(42), atom.Load(), "Store didn't set the correct value.")
|
||||
}
|
||||
|
||||
func TestInt64(t *testing.T) {
|
||||
atom := NewInt64(42)
|
||||
|
||||
require.Equal(t, int64(42), atom.Load(), "Load didn't work.")
|
||||
require.Equal(t, int64(46), atom.Add(4), "Add didn't work.")
|
||||
require.Equal(t, int64(44), atom.Sub(2), "Sub didn't work.")
|
||||
require.Equal(t, int64(45), atom.Inc(), "Inc didn't work.")
|
||||
require.Equal(t, int64(44), atom.Dec(), "Dec didn't work.")
|
||||
|
||||
require.True(t, atom.CAS(44, 0), "CAS didn't report a swap.")
|
||||
require.Equal(t, int64(0), atom.Load(), "CAS didn't set the correct value.")
|
||||
|
||||
require.Equal(t, int64(0), atom.Swap(1), "Swap didn't return the old value.")
|
||||
require.Equal(t, int64(1), atom.Load(), "Swap didn't set the correct value.")
|
||||
|
||||
atom.Store(42)
|
||||
require.Equal(t, int64(42), atom.Load(), "Store didn't set the correct value.")
|
||||
}
|
||||
|
||||
func TestUint32(t *testing.T) {
|
||||
atom := NewUint32(42)
|
||||
|
||||
require.Equal(t, uint32(42), atom.Load(), "Load didn't work.")
|
||||
require.Equal(t, uint32(46), atom.Add(4), "Add didn't work.")
|
||||
require.Equal(t, uint32(44), atom.Sub(2), "Sub didn't work.")
|
||||
require.Equal(t, uint32(45), atom.Inc(), "Inc didn't work.")
|
||||
require.Equal(t, uint32(44), atom.Dec(), "Dec didn't work.")
|
||||
|
||||
require.True(t, atom.CAS(44, 0), "CAS didn't report a swap.")
|
||||
require.Equal(t, uint32(0), atom.Load(), "CAS didn't set the correct value.")
|
||||
|
||||
require.Equal(t, uint32(0), atom.Swap(1), "Swap didn't return the old value.")
|
||||
require.Equal(t, uint32(1), atom.Load(), "Swap didn't set the correct value.")
|
||||
|
||||
atom.Store(42)
|
||||
require.Equal(t, uint32(42), atom.Load(), "Store didn't set the correct value.")
|
||||
}
|
||||
|
||||
func TestUint64(t *testing.T) {
|
||||
atom := NewUint64(42)
|
||||
|
||||
require.Equal(t, uint64(42), atom.Load(), "Load didn't work.")
|
||||
require.Equal(t, uint64(46), atom.Add(4), "Add didn't work.")
|
||||
require.Equal(t, uint64(44), atom.Sub(2), "Sub didn't work.")
|
||||
require.Equal(t, uint64(45), atom.Inc(), "Inc didn't work.")
|
||||
require.Equal(t, uint64(44), atom.Dec(), "Dec didn't work.")
|
||||
|
||||
require.True(t, atom.CAS(44, 0), "CAS didn't report a swap.")
|
||||
require.Equal(t, uint64(0), atom.Load(), "CAS didn't set the correct value.")
|
||||
|
||||
require.Equal(t, uint64(0), atom.Swap(1), "Swap didn't return the old value.")
|
||||
require.Equal(t, uint64(1), atom.Load(), "Swap didn't set the correct value.")
|
||||
|
||||
atom.Store(42)
|
||||
require.Equal(t, uint64(42), atom.Load(), "Store didn't set the correct value.")
|
||||
}
|
||||
|
||||
func TestBool(t *testing.T) {
|
||||
atom := NewBool(false)
|
||||
require.False(t, atom.Toggle(), "Expected swap to return previous value.")
|
||||
require.True(t, atom.Load(), "Unexpected state after swap.")
|
||||
|
||||
atom.Store(false)
|
||||
require.False(t, atom.Load(), "Unexpected state after store.")
|
||||
|
||||
prev := atom.Swap(false)
|
||||
require.False(t, prev, "Expected Swap to return previous value.")
|
||||
|
||||
prev = atom.Swap(true)
|
||||
require.False(t, prev, "Expected Swap to return previous value.")
|
||||
}
|
||||
|
||||
func TestFloat64(t *testing.T) {
|
||||
atom := NewFloat64(4.2)
|
||||
|
||||
require.Equal(t, float64(4.2), atom.Load(), "Load didn't work.")
|
||||
|
||||
require.True(t, atom.CAS(4.2, 0.5), "CAS didn't report a swap.")
|
||||
require.Equal(t, float64(0.5), atom.Load(), "CAS didn't set the correct value.")
|
||||
require.False(t, atom.CAS(0.0, 1.5), "CAS reported a swap.")
|
||||
|
||||
atom.Store(42.0)
|
||||
require.Equal(t, float64(42.0), atom.Load(), "Store didn't set the correct value.")
|
||||
require.Equal(t, float64(42.5), atom.Add(0.5), "Add didn't work.")
|
||||
require.Equal(t, float64(42.0), atom.Sub(0.5), "Sub didn't work.")
|
||||
}
|
||||
|
||||
func TestValue(t *testing.T) {
|
||||
var v Value
|
||||
assert.Nil(t, v.Load(), "initial Value is not nil")
|
||||
|
||||
v.Store(42)
|
||||
assert.Equal(t, 42, v.Load())
|
||||
|
||||
v.Store(84)
|
||||
assert.Equal(t, 84, v.Load())
|
||||
|
||||
assert.Panics(t, func() { v.Store("foo") })
|
||||
}
|
||||
43
vendor/go.uber.org/atomic/example_test.go
generated
vendored
Normal file
43
vendor/go.uber.org/atomic/example_test.go
generated
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
// Copyright (c) 2016 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 atomic_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"go.uber.org/atomic"
|
||||
)
|
||||
|
||||
func Example() {
|
||||
// Uint32 is a thin wrapper around the primitive uint32 type.
|
||||
var atom atomic.Uint32
|
||||
|
||||
// The wrapper ensures that all operations are atomic.
|
||||
atom.Store(42)
|
||||
fmt.Println(atom.Inc())
|
||||
fmt.Println(atom.CAS(43, 0))
|
||||
fmt.Println(atom.Load())
|
||||
|
||||
// Output:
|
||||
// 43
|
||||
// true
|
||||
// 0
|
||||
}
|
||||
17
vendor/go.uber.org/atomic/glide.lock
generated
vendored
Normal file
17
vendor/go.uber.org/atomic/glide.lock
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
hash: f14d51408e3e0e4f73b34e4039484c78059cd7fc5f4996fdd73db20dc8d24f53
|
||||
updated: 2016-10-27T00:10:51.16960137-07:00
|
||||
imports: []
|
||||
testImports:
|
||||
- name: github.com/davecgh/go-spew
|
||||
version: 5215b55f46b2b919f50a1df0eaa5886afe4e3b3d
|
||||
subpackages:
|
||||
- spew
|
||||
- name: github.com/pmezard/go-difflib
|
||||
version: d8ed2627bdf02c080bf22230dbb337003b7aba2d
|
||||
subpackages:
|
||||
- difflib
|
||||
- name: github.com/stretchr/testify
|
||||
version: d77da356e56a7428ad25149ca77381849a6a5232
|
||||
subpackages:
|
||||
- assert
|
||||
- require
|
||||
6
vendor/go.uber.org/atomic/glide.yaml
generated
vendored
Normal file
6
vendor/go.uber.org/atomic/glide.yaml
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
package: go.uber.org/atomic
|
||||
testImport:
|
||||
- package: github.com/stretchr/testify
|
||||
subpackages:
|
||||
- assert
|
||||
- require
|
||||
40
vendor/go.uber.org/atomic/scripts/cover.sh
generated
vendored
Executable file
40
vendor/go.uber.org/atomic/scripts/cover.sh
generated
vendored
Executable file
@@ -0,0 +1,40 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
COVER=cover
|
||||
ROOT_PKG=go.uber.org/atomic
|
||||
|
||||
if [[ -d "$COVER" ]]; then
|
||||
rm -rf "$COVER"
|
||||
fi
|
||||
mkdir -p "$COVER"
|
||||
|
||||
i=0
|
||||
for pkg in "$@"; do
|
||||
i=$((i + 1))
|
||||
|
||||
extracoverpkg=""
|
||||
if [[ -f "$GOPATH/src/$pkg/.extra-coverpkg" ]]; then
|
||||
extracoverpkg=$( \
|
||||
sed -e "s|^|$pkg/|g" < "$GOPATH/src/$pkg/.extra-coverpkg" \
|
||||
| tr '\n' ',')
|
||||
fi
|
||||
|
||||
coverpkg=$(go list -json "$pkg" | jq -r '
|
||||
.Deps
|
||||
| map(select(startswith("'"$ROOT_PKG"'")))
|
||||
| map(select(contains("/vendor/") | not))
|
||||
| . + ["'"$pkg"'"]
|
||||
| join(",")
|
||||
')
|
||||
if [[ -n "$extracoverpkg" ]]; then
|
||||
coverpkg="$extracoverpkg$coverpkg"
|
||||
fi
|
||||
|
||||
go test \
|
||||
-coverprofile "$COVER/cover.${i}.out" -coverpkg "$coverpkg" \
|
||||
-v "$pkg"
|
||||
done
|
||||
|
||||
gocovmerge "$COVER"/*.out > cover.out
|
||||
26
vendor/go.uber.org/atomic/scripts/test-ubergo.sh
generated
vendored
Executable file
26
vendor/go.uber.org/atomic/scripts/test-ubergo.sh
generated
vendored
Executable file
@@ -0,0 +1,26 @@
|
||||
#!/bin/bash
|
||||
set -euox pipefail
|
||||
IFS=$'\n\t'
|
||||
|
||||
# This script creates a fake GOPATH, symlinks in the current
|
||||
# directory as uber-go/atomic and verifies that tests still pass.
|
||||
|
||||
WORK_DIR=`mktemp -d`
|
||||
function cleanup {
|
||||
rm -rf "$WORK_DIR"
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
|
||||
export GOPATH="$WORK_DIR"
|
||||
PKG_PARENT="$WORK_DIR/src/github.com/uber-go"
|
||||
PKG_DIR="$PKG_PARENT/atomic"
|
||||
|
||||
mkdir -p "$PKG_PARENT"
|
||||
cp -R `pwd` "$PKG_DIR"
|
||||
cd "$PKG_DIR"
|
||||
|
||||
# The example imports go.uber.org, fix the import.
|
||||
sed -e 's/go.uber.org\/atomic/github.com\/uber-go\/atomic/' -i="" example_test.go
|
||||
|
||||
make test
|
||||
140
vendor/go.uber.org/atomic/stress_test.go
generated
vendored
Normal file
140
vendor/go.uber.org/atomic/stress_test.go
generated
vendored
Normal file
@@ -0,0 +1,140 @@
|
||||
// Copyright (c) 2016 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 atomic
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
"sync"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const (
|
||||
_parallelism = 4
|
||||
_iterations = 1000
|
||||
)
|
||||
|
||||
func runStress(f func()) {
|
||||
defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(_parallelism))
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(_parallelism)
|
||||
for i := 0; i < _parallelism; i++ {
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
for j := 0; j < _iterations; j++ {
|
||||
f()
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
func TestStressInt32(t *testing.T) {
|
||||
var atom Int32
|
||||
runStress(func() {
|
||||
atom.Load()
|
||||
atom.Add(1)
|
||||
atom.Sub(2)
|
||||
atom.Inc()
|
||||
atom.Dec()
|
||||
atom.CAS(1, 0)
|
||||
atom.Swap(5)
|
||||
atom.Store(1)
|
||||
})
|
||||
}
|
||||
|
||||
func TestStressInt64(t *testing.T) {
|
||||
var atom Int64
|
||||
runStress(func() {
|
||||
atom.Load()
|
||||
atom.Add(1)
|
||||
atom.Sub(2)
|
||||
atom.Inc()
|
||||
atom.Dec()
|
||||
atom.CAS(1, 0)
|
||||
atom.Swap(5)
|
||||
atom.Store(1)
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
func TestStressUint32(t *testing.T) {
|
||||
var atom Uint32
|
||||
runStress(func() {
|
||||
atom.Load()
|
||||
atom.Add(1)
|
||||
atom.Sub(2)
|
||||
atom.Inc()
|
||||
atom.Dec()
|
||||
atom.CAS(1, 0)
|
||||
atom.Swap(5)
|
||||
atom.Store(1)
|
||||
})
|
||||
}
|
||||
|
||||
func TestStressUint64(t *testing.T) {
|
||||
var atom Uint64
|
||||
runStress(func() {
|
||||
atom.Load()
|
||||
atom.Add(1)
|
||||
atom.Sub(2)
|
||||
atom.Inc()
|
||||
atom.Dec()
|
||||
atom.CAS(1, 0)
|
||||
atom.Swap(5)
|
||||
atom.Store(1)
|
||||
})
|
||||
}
|
||||
|
||||
func TestStressFloat64(t *testing.T) {
|
||||
var atom Float64
|
||||
runStress(func() {
|
||||
atom.Load()
|
||||
atom.CAS(1.0, 0.1)
|
||||
atom.Add(1.1)
|
||||
atom.Sub(0.2)
|
||||
atom.Store(1.0)
|
||||
})
|
||||
}
|
||||
|
||||
func TestStressBool(t *testing.T) {
|
||||
var atom Bool
|
||||
runStress(func() {
|
||||
atom.Load()
|
||||
atom.Store(false)
|
||||
atom.Swap(true)
|
||||
atom.Load()
|
||||
atom.Toggle()
|
||||
atom.Toggle()
|
||||
})
|
||||
}
|
||||
|
||||
func TestStressString(t *testing.T) {
|
||||
var atom String
|
||||
runStress(func() {
|
||||
atom.Load()
|
||||
atom.Store("abc")
|
||||
atom.Load()
|
||||
atom.Store("def")
|
||||
|
||||
})
|
||||
}
|
||||
51
vendor/go.uber.org/atomic/string.go
generated
vendored
Normal file
51
vendor/go.uber.org/atomic/string.go
generated
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
// Copyright (c) 2016 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 atomic
|
||||
|
||||
import "sync/atomic"
|
||||
|
||||
// String is an atomic type-safe wrapper around atomic.Value for strings.
|
||||
type String struct{ v atomic.Value }
|
||||
|
||||
// NewString creates a String.
|
||||
func NewString(str string) *String {
|
||||
s := &String{}
|
||||
if str != "" {
|
||||
s.Store(str)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// Load atomically loads the wrapped string.
|
||||
func (s *String) Load() string {
|
||||
v := s.v.Load()
|
||||
if v == nil {
|
||||
return ""
|
||||
}
|
||||
return v.(string)
|
||||
}
|
||||
|
||||
// Store atomically stores the passed string.
|
||||
// Note: Converting the string to an interface{} to store in the atomic.Value
|
||||
// requires an allocation.
|
||||
func (s *String) Store(str string) {
|
||||
s.v.Store(str)
|
||||
}
|
||||
43
vendor/go.uber.org/atomic/string_test.go
generated
vendored
Normal file
43
vendor/go.uber.org/atomic/string_test.go
generated
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
// Copyright (c) 2016 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 atomic
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestStringNoInitialValue(t *testing.T) {
|
||||
atom := &String{}
|
||||
require.Equal(t, "", atom.Load(), "Initial value should be blank string")
|
||||
}
|
||||
|
||||
func TestString(t *testing.T) {
|
||||
atom := NewString("")
|
||||
require.Equal(t, "", atom.Load(), "Expected Load to return initialized value")
|
||||
|
||||
atom.Store("abc")
|
||||
require.Equal(t, "abc", atom.Load(), "Unexpected value after Store")
|
||||
|
||||
atom = NewString("bcd")
|
||||
require.Equal(t, "bcd", atom.Load(), "Expected Load to return initialized value")
|
||||
}
|
||||
15
vendor/go.uber.org/multierr/.codecov.yml
generated
vendored
Normal file
15
vendor/go.uber.org/multierr/.codecov.yml
generated
vendored
Normal file
@@ -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
|
||||
|
||||
33
vendor/go.uber.org/multierr/.travis.yml
generated
vendored
Normal file
33
vendor/go.uber.org/multierr/.travis.yml
generated
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
sudo: false
|
||||
language: go
|
||||
go_import_path: go.uber.org/multierr
|
||||
|
||||
env:
|
||||
global:
|
||||
- GO15VENDOREXPERIMENT=1
|
||||
|
||||
go:
|
||||
- 1.7
|
||||
- 1.8
|
||||
- tip
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- vendor
|
||||
|
||||
before_install:
|
||||
- go version
|
||||
|
||||
install:
|
||||
- |
|
||||
set -e
|
||||
make install_ci
|
||||
|
||||
script:
|
||||
- |
|
||||
set -e
|
||||
make lint
|
||||
make test_ci
|
||||
|
||||
after_success:
|
||||
- bash <(curl -s https://codecov.io/bash)
|
||||
28
vendor/go.uber.org/multierr/CHANGELOG.md
generated
vendored
Normal file
28
vendor/go.uber.org/multierr/CHANGELOG.md
generated
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
Releases
|
||||
========
|
||||
|
||||
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
|
||||
19
vendor/go.uber.org/multierr/LICENSE.txt
generated
vendored
Normal file
19
vendor/go.uber.org/multierr/LICENSE.txt
generated
vendored
Normal file
@@ -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.
|
||||
74
vendor/go.uber.org/multierr/Makefile
generated
vendored
Normal file
74
vendor/go.uber.org/multierr/Makefile
generated
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
export GO15VENDOREXPERIMENT=1
|
||||
|
||||
PACKAGES := $(shell glide nv)
|
||||
|
||||
GO_FILES := $(shell \
|
||||
find . '(' -path '*/.*' -o -path './vendor' ')' -prune \
|
||||
-o -name '*.go' -print | cut -b3-)
|
||||
|
||||
.PHONY: install
|
||||
install:
|
||||
glide --version || go get github.com/Masterminds/glide
|
||||
glide install
|
||||
|
||||
.PHONY: build
|
||||
build:
|
||||
go build -i $(PACKAGES)
|
||||
|
||||
.PHONY: test
|
||||
test:
|
||||
go test -cover -race $(PACKAGES)
|
||||
|
||||
.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: govet
|
||||
govet:
|
||||
$(eval VET_LOG := $(shell mktemp -t govet.XXXXX))
|
||||
@go vet $(PACKAGES) 2>&1 \
|
||||
| grep -v '^exit status' > $(VET_LOG) || true
|
||||
@[ ! -s "$(VET_LOG)" ] || (echo "govet failed:" | cat - $(VET_LOG) && false)
|
||||
|
||||
.PHONY: golint
|
||||
golint:
|
||||
@go get github.com/golang/lint/golint
|
||||
$(eval LINT_LOG := $(shell mktemp -t golint.XXXXX))
|
||||
@cat /dev/null > $(LINT_LOG)
|
||||
@$(foreach pkg, $(PACKAGES), golint $(pkg) >> $(LINT_LOG) || true;)
|
||||
@[ ! -s "$(LINT_LOG)" ] || (echo "golint failed:" | cat - $(LINT_LOG) && false)
|
||||
|
||||
.PHONY: staticcheck
|
||||
staticcheck:
|
||||
@go get honnef.co/go/tools/cmd/staticcheck
|
||||
$(eval STATICCHECK_LOG := $(shell mktemp -t staticcheck.XXXXX))
|
||||
@staticcheck $(PACKAGES) 2>&1 > $(STATICCHECK_LOG) || true
|
||||
@[ ! -s "$(STATICCHECK_LOG)" ] || (echo "staticcheck failed:" | cat - $(STATICCHECK_LOG) && false)
|
||||
|
||||
.PHONY: lint
|
||||
lint: gofmt govet golint staticcheck
|
||||
|
||||
.PHONY: cover
|
||||
cover:
|
||||
./scripts/cover.sh $(shell go list $(PACKAGES))
|
||||
go tool cover -html=cover.out -o cover.html
|
||||
|
||||
update-license:
|
||||
@go get go.uber.org/tools/update-license
|
||||
@update-license \
|
||||
$(shell go list -json $(PACKAGES) | \
|
||||
jq -r '.Dir + "/" + (.GoFiles | .[])')
|
||||
|
||||
##############################################################################
|
||||
|
||||
.PHONY: install_ci
|
||||
install_ci: install
|
||||
go get github.com/wadey/gocovmerge
|
||||
go get github.com/mattn/goveralls
|
||||
go get golang.org/x/tools/cmd/cover
|
||||
|
||||
.PHONY: test_ci
|
||||
test_ci: install_ci
|
||||
./scripts/cover.sh $(shell go list $(PACKAGES))
|
||||
23
vendor/go.uber.org/multierr/README.md
generated
vendored
Normal file
23
vendor/go.uber.org/multierr/README.md
generated
vendored
Normal file
@@ -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.org/uber-go/multierr.svg?branch=master
|
||||
[cov-img]: https://codecov.io/gh/uber-go/multierr/branch/master/graph/badge.svg
|
||||
[ci]: https://travis-ci.org/uber-go/multierr
|
||||
[cov]: https://codecov.io/gh/uber-go/multierr
|
||||
62
vendor/go.uber.org/multierr/benchmarks_test.go
generated
vendored
Normal file
62
vendor/go.uber.org/multierr/benchmarks_test.go
generated
vendored
Normal file
@@ -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)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
401
vendor/go.uber.org/multierr/error.go
generated
vendored
Normal file
401
vendor/go.uber.org/multierr/error.go
generated
vendored
Normal file
@@ -0,0 +1,401 @@
|
||||
// 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 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.Combine(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:")
|
||||
// }
|
||||
//
|
||||
// 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("; ")
|
||||
|
||||
_newline = []byte("\n")
|
||||
|
||||
// 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, the returned slice is empty.
|
||||
//
|
||||
// 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:])
|
||||
}
|
||||
511
vendor/go.uber.org/multierr/error_test.go
generated
vendored
Normal file
511
vendor/go.uber.org/multierr/error_test.go
generated
vendored
Normal file
@@ -0,0 +1,511 @@
|
||||
// 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"
|
||||
"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())
|
||||
}
|
||||
72
vendor/go.uber.org/multierr/example_test.go
generated
vendored
Normal file
72
vendor/go.uber.org/multierr/example_test.go
generated
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
// 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
|
||||
}
|
||||
19
vendor/go.uber.org/multierr/glide.lock
generated
vendored
Normal file
19
vendor/go.uber.org/multierr/glide.lock
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
hash: b53b5e9a84b9cb3cc4b2d0499e23da2feca1eec318ce9bb717ecf35bf24bf221
|
||||
updated: 2017-04-10T13:34:45.671678062-07:00
|
||||
imports:
|
||||
- name: go.uber.org/atomic
|
||||
version: 3b8db5e93c4c02efbc313e17b2e796b0914a01fb
|
||||
testImports:
|
||||
- name: github.com/davecgh/go-spew
|
||||
version: 6d212800a42e8ab5c146b8ace3490ee17e5225f9
|
||||
subpackages:
|
||||
- spew
|
||||
- name: github.com/pmezard/go-difflib
|
||||
version: d8ed2627bdf02c080bf22230dbb337003b7aba2d
|
||||
subpackages:
|
||||
- difflib
|
||||
- name: github.com/stretchr/testify
|
||||
version: 69483b4bd14f5845b5a1e55bca19e954e827f1d0
|
||||
subpackages:
|
||||
- assert
|
||||
- require
|
||||
8
vendor/go.uber.org/multierr/glide.yaml
generated
vendored
Normal file
8
vendor/go.uber.org/multierr/glide.yaml
generated
vendored
Normal file
@@ -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
|
||||
40
vendor/go.uber.org/multierr/scripts/cover.sh
generated
vendored
Executable file
40
vendor/go.uber.org/multierr/scripts/cover.sh
generated
vendored
Executable file
@@ -0,0 +1,40 @@
|
||||
#!/bin/bash -e
|
||||
|
||||
COVER=cover
|
||||
ROOT_PKG=go.uber.org/multierr
|
||||
|
||||
if [[ -d "$COVER" ]]; then
|
||||
rm -rf "$COVER"
|
||||
fi
|
||||
mkdir -p "$COVER"
|
||||
|
||||
i=0
|
||||
for pkg in "$@"; do
|
||||
i=$((i + 1))
|
||||
|
||||
extracoverpkg=""
|
||||
if [[ -f "$GOPATH/src/$pkg/.extra-coverpkg" ]]; then
|
||||
extracoverpkg=$( \
|
||||
sed -e "s|^|$pkg/|g" < "$GOPATH/src/$pkg/.extra-coverpkg" \
|
||||
| tr '\n' ',')
|
||||
fi
|
||||
|
||||
coverpkg=$(go list -json "$pkg" | jq -r '
|
||||
.Deps
|
||||
| . + ["'"$pkg"'"]
|
||||
| map
|
||||
( select(startswith("'"$ROOT_PKG"'"))
|
||||
| select(contains("/vendor/") | not)
|
||||
)
|
||||
| join(",")
|
||||
')
|
||||
if [[ -n "$extracoverpkg" ]]; then
|
||||
coverpkg="$extracoverpkg$coverpkg"
|
||||
fi
|
||||
|
||||
go test \
|
||||
-coverprofile "$COVER/cover.${i}.out" -coverpkg "$coverpkg" \
|
||||
-v "$pkg"
|
||||
done
|
||||
|
||||
gocovmerge "$COVER"/*.out > cover.out
|
||||
Reference in New Issue
Block a user