diff --git a/Gopkg.lock b/Gopkg.lock
index 85471fc1cc0d..735576589d93 100644
--- a/Gopkg.lock
+++ b/Gopkg.lock
@@ -263,14 +263,6 @@
revision = "2eee05ed794112d45db504eb05aa693efd2b8b09"
version = "v0.1.0"
-[[projects]]
- branch = "master"
- digest = "1:0550b06297ebdd7dde9a20c5129f941abfdba6e47f8111bfdd0f1830c58dc800"
- name = "github.com/juju/errors"
- packages = ["."]
- pruneopts = "NUT"
- revision = "c7d06af17c68cd34c835053720b21f6549d9b0ee"
-
[[projects]]
digest = "1:d0164259ed17929689df11205194d80288e8ae25351778f7a3421a24774c36f8"
name = "github.com/mattn/go-shellwords"
@@ -334,6 +326,14 @@
pruneopts = "NUT"
revision = "279515615485b0f2d12f1421cc412fe2784e0190"
+[[projects]]
+ digest = "1:5cf3f025cbee5951a4ee961de067c8a89fc95a5adabead774f82822efabab121"
+ name = "github.com/pkg/errors"
+ packages = ["."]
+ pruneopts = "NUT"
+ revision = "645ef00459ed84a119197bfb8d8205042c6df63d"
+ version = "v0.8.0"
+
[[projects]]
digest = "1:8d8f554bbb62fb7aecf661b85b25e227f6ab6cfe2b4395ea65ef478bfc174940"
name = "github.com/prometheus/client_golang"
@@ -637,7 +637,6 @@
"github.com/google/btree",
"github.com/gorilla/mux",
"github.com/grpc-ecosystem/go-grpc-prometheus",
- "github.com/juju/errors",
"github.com/mattn/go-shellwords",
"github.com/montanaflynn/stats",
"github.com/opentracing/opentracing-go",
@@ -645,6 +644,7 @@
"github.com/pingcap/kvproto/pkg/eraftpb",
"github.com/pingcap/kvproto/pkg/metapb",
"github.com/pingcap/kvproto/pkg/pdpb",
+ "github.com/pkg/errors",
"github.com/prometheus/client_golang/prometheus",
"github.com/prometheus/client_golang/prometheus/push",
"github.com/sirupsen/logrus",
diff --git a/Gopkg.toml b/Gopkg.toml
index 1ff28a85da4f..b56494b4163c 100644
--- a/Gopkg.toml
+++ b/Gopkg.toml
@@ -35,3 +35,7 @@
[[constraint]]
name = "github.com/etcd-io/gofail"
branch = "master"
+
+[[constraint]]
+ name = "github.com/pkg/errors"
+ version = "0.8.0"
diff --git a/vendor/github.com/juju/errors/LICENSE b/vendor/github.com/juju/errors/LICENSE
deleted file mode 100644
index ade9307b390c..000000000000
--- a/vendor/github.com/juju/errors/LICENSE
+++ /dev/null
@@ -1,191 +0,0 @@
-All files in this repository are licensed as follows. If you contribute
-to this repository, it is assumed that you license your contribution
-under the same license unless you state otherwise.
-
-All files Copyright (C) 2015 Canonical Ltd. unless otherwise specified in the file.
-
-This software is licensed under the LGPLv3, included below.
-
-As a special exception to the GNU Lesser General Public License version 3
-("LGPL3"), the copyright holders of this Library give you permission to
-convey to a third party a Combined Work that links statically or dynamically
-to this Library without providing any Minimal Corresponding Source or
-Minimal Application Code as set out in 4d or providing the installation
-information set out in section 4e, provided that you comply with the other
-provisions of LGPL3 and provided that you meet, for the Application the
-terms and conditions of the license(s) which apply to the Application.
-
-Except as stated in this special exception, the provisions of LGPL3 will
-continue to comply in full to this Library. If you modify this Library, you
-may apply this exception to your version of this Library, but you are not
-obliged to do so. If you do not wish to do so, delete this exception
-statement from your version. This exception does not (and cannot) modify any
-license terms which apply to the Application, with which you must still
-comply.
-
-
- GNU LESSER GENERAL PUBLIC LICENSE
- Version 3, 29 June 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc.
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-
- This version of the GNU Lesser General Public License incorporates
-the terms and conditions of version 3 of the GNU General Public
-License, supplemented by the additional permissions listed below.
-
- 0. Additional Definitions.
-
- As used herein, "this License" refers to version 3 of the GNU Lesser
-General Public License, and the "GNU GPL" refers to version 3 of the GNU
-General Public License.
-
- "The Library" refers to a covered work governed by this License,
-other than an Application or a Combined Work as defined below.
-
- An "Application" is any work that makes use of an interface provided
-by the Library, but which is not otherwise based on the Library.
-Defining a subclass of a class defined by the Library is deemed a mode
-of using an interface provided by the Library.
-
- A "Combined Work" is a work produced by combining or linking an
-Application with the Library. The particular version of the Library
-with which the Combined Work was made is also called the "Linked
-Version".
-
- The "Minimal Corresponding Source" for a Combined Work means the
-Corresponding Source for the Combined Work, excluding any source code
-for portions of the Combined Work that, considered in isolation, are
-based on the Application, and not on the Linked Version.
-
- The "Corresponding Application Code" for a Combined Work means the
-object code and/or source code for the Application, including any data
-and utility programs needed for reproducing the Combined Work from the
-Application, but excluding the System Libraries of the Combined Work.
-
- 1. Exception to Section 3 of the GNU GPL.
-
- You may convey a covered work under sections 3 and 4 of this License
-without being bound by section 3 of the GNU GPL.
-
- 2. Conveying Modified Versions.
-
- If you modify a copy of the Library, and, in your modifications, a
-facility refers to a function or data to be supplied by an Application
-that uses the facility (other than as an argument passed when the
-facility is invoked), then you may convey a copy of the modified
-version:
-
- a) under this License, provided that you make a good faith effort to
- ensure that, in the event an Application does not supply the
- function or data, the facility still operates, and performs
- whatever part of its purpose remains meaningful, or
-
- b) under the GNU GPL, with none of the additional permissions of
- this License applicable to that copy.
-
- 3. Object Code Incorporating Material from Library Header Files.
-
- The object code form of an Application may incorporate material from
-a header file that is part of the Library. You may convey such object
-code under terms of your choice, provided that, if the incorporated
-material is not limited to numerical parameters, data structure
-layouts and accessors, or small macros, inline functions and templates
-(ten or fewer lines in length), you do both of the following:
-
- a) Give prominent notice with each copy of the object code that the
- Library is used in it and that the Library and its use are
- covered by this License.
-
- b) Accompany the object code with a copy of the GNU GPL and this license
- document.
-
- 4. Combined Works.
-
- You may convey a Combined Work under terms of your choice that,
-taken together, effectively do not restrict modification of the
-portions of the Library contained in the Combined Work and reverse
-engineering for debugging such modifications, if you also do each of
-the following:
-
- a) Give prominent notice with each copy of the Combined Work that
- the Library is used in it and that the Library and its use are
- covered by this License.
-
- b) Accompany the Combined Work with a copy of the GNU GPL and this license
- document.
-
- c) For a Combined Work that displays copyright notices during
- execution, include the copyright notice for the Library among
- these notices, as well as a reference directing the user to the
- copies of the GNU GPL and this license document.
-
- d) Do one of the following:
-
- 0) Convey the Minimal Corresponding Source under the terms of this
- License, and the Corresponding Application Code in a form
- suitable for, and under terms that permit, the user to
- recombine or relink the Application with a modified version of
- the Linked Version to produce a modified Combined Work, in the
- manner specified by section 6 of the GNU GPL for conveying
- Corresponding Source.
-
- 1) Use a suitable shared library mechanism for linking with the
- Library. A suitable mechanism is one that (a) uses at run time
- a copy of the Library already present on the user's computer
- system, and (b) will operate properly with a modified version
- of the Library that is interface-compatible with the Linked
- Version.
-
- e) Provide Installation Information, but only if you would otherwise
- be required to provide such information under section 6 of the
- GNU GPL, and only to the extent that such information is
- necessary to install and execute a modified version of the
- Combined Work produced by recombining or relinking the
- Application with a modified version of the Linked Version. (If
- you use option 4d0, the Installation Information must accompany
- the Minimal Corresponding Source and Corresponding Application
- Code. If you use option 4d1, you must provide the Installation
- Information in the manner specified by section 6 of the GNU GPL
- for conveying Corresponding Source.)
-
- 5. Combined Libraries.
-
- You may place library facilities that are a work based on the
-Library side by side in a single library together with other library
-facilities that are not Applications and are not covered by this
-License, and convey such a combined library under terms of your
-choice, if you do both of the following:
-
- a) Accompany the combined library with a copy of the same work based
- on the Library, uncombined with any other library facilities,
- conveyed under the terms of this License.
-
- b) Give prominent notice with the combined library that part of it
- is a work based on the Library, and explaining where to find the
- accompanying uncombined form of the same work.
-
- 6. Revised Versions of the GNU Lesser General Public License.
-
- The Free Software Foundation may publish revised and/or new versions
-of the GNU Lesser General Public License from time to time. Such new
-versions will be similar in spirit to the present version, but may
-differ in detail to address new problems or concerns.
-
- Each version is given a distinguishing version number. If the
-Library as you received it specifies that a certain numbered version
-of the GNU Lesser General Public License "or any later version"
-applies to it, you have the option of following the terms and
-conditions either of that published version or of any later version
-published by the Free Software Foundation. If the Library as you
-received it does not specify a version number of the GNU Lesser
-General Public License, you may choose any version of the GNU Lesser
-General Public License ever published by the Free Software Foundation.
-
- If the Library as you received it specifies that a proxy can decide
-whether future versions of the GNU Lesser General Public License shall
-apply, that proxy's public statement of acceptance of any version is
-permanent authorization for you to choose that version for the
-Library.
diff --git a/vendor/github.com/juju/errors/doc.go b/vendor/github.com/juju/errors/doc.go
deleted file mode 100644
index 35b119aa3459..000000000000
--- a/vendor/github.com/juju/errors/doc.go
+++ /dev/null
@@ -1,81 +0,0 @@
-// Copyright 2013, 2014 Canonical Ltd.
-// Licensed under the LGPLv3, see LICENCE file for details.
-
-/*
-[godoc-link-here]
-
-The juju/errors provides an easy way to annotate errors without losing the
-orginal error context.
-
-The exported `New` and `Errorf` functions are designed to replace the
-`errors.New` and `fmt.Errorf` functions respectively. The same underlying
-error is there, but the package also records the location at which the error
-was created.
-
-A primary use case for this library is to add extra context any time an
-error is returned from a function.
-
- if err := SomeFunc(); err != nil {
- return err
- }
-
-This instead becomes:
-
- if err := SomeFunc(); err != nil {
- return errors.Trace(err)
- }
-
-which just records the file and line number of the Trace call, or
-
- if err := SomeFunc(); err != nil {
- return errors.Annotate(err, "more context")
- }
-
-which also adds an annotation to the error.
-
-When you want to check to see if an error is of a particular type, a helper
-function is normally exported by the package that returned the error, like the
-`os` package does. The underlying cause of the error is available using the
-`Cause` function.
-
- os.IsNotExist(errors.Cause(err))
-
-The result of the `Error()` call on an annotated error is the annotations joined
-with colons, then the result of the `Error()` method for the underlying error
-that was the cause.
-
- err := errors.Errorf("original")
- err = errors.Annotatef(err, "context")
- err = errors.Annotatef(err, "more context")
- err.Error() -> "more context: context: original"
-
-Obviously recording the file, line and functions is not very useful if you
-cannot get them back out again.
-
- errors.ErrorStack(err)
-
-will return something like:
-
- first error
- github.com/juju/errors/annotation_test.go:193:
- github.com/juju/errors/annotation_test.go:194: annotation
- github.com/juju/errors/annotation_test.go:195:
- github.com/juju/errors/annotation_test.go:196: more context
- github.com/juju/errors/annotation_test.go:197:
-
-The first error was generated by an external system, so there was no location
-associated. The second, fourth, and last lines were generated with Trace calls,
-and the other two through Annotate.
-
-Sometimes when responding to an error you want to return a more specific error
-for the situation.
-
- if err := FindField(field); err != nil {
- return errors.Wrap(err, errors.NotFoundf(field))
- }
-
-This returns an error where the complete error stack is still available, and
-`errors.Cause()` will return the `NotFound` error.
-
-*/
-package errors
diff --git a/vendor/github.com/juju/errors/error.go b/vendor/github.com/juju/errors/error.go
deleted file mode 100644
index b7df73589e68..000000000000
--- a/vendor/github.com/juju/errors/error.go
+++ /dev/null
@@ -1,172 +0,0 @@
-// Copyright 2014 Canonical Ltd.
-// Licensed under the LGPLv3, see LICENCE file for details.
-
-package errors
-
-import (
- "fmt"
- "reflect"
- "runtime"
-)
-
-// Err holds a description of an error along with information about
-// where the error was created.
-//
-// It may be embedded in custom error types to add extra information that
-// this errors package can understand.
-type Err struct {
- // message holds an annotation of the error.
- message string
-
- // cause holds the cause of the error as returned
- // by the Cause method.
- cause error
-
- // previous holds the previous error in the error stack, if any.
- previous error
-
- // file and line hold the source code location where the error was
- // created.
- file string
- line int
-}
-
-// NewErr is used to return an Err for the purpose of embedding in other
-// structures. The location is not specified, and needs to be set with a call
-// to SetLocation.
-//
-// For example:
-// type FooError struct {
-// errors.Err
-// code int
-// }
-//
-// func NewFooError(code int) error {
-// err := &FooError{errors.NewErr("foo"), code}
-// err.SetLocation(1)
-// return err
-// }
-func NewErr(format string, args ...interface{}) Err {
- return Err{
- message: fmt.Sprintf(format, args...),
- }
-}
-
-// NewErrWithCause is used to return an Err with case by other error for the purpose of embedding in other
-// structures. The location is not specified, and needs to be set with a call
-// to SetLocation.
-//
-// For example:
-// type FooError struct {
-// errors.Err
-// code int
-// }
-//
-// func (e *FooError) Annotate(format string, args ...interface{}) error {
-// err := &FooError{errors.NewErrWithCause(e.Err, format, args...), e.code}
-// err.SetLocation(1)
-// return err
-// })
-func NewErrWithCause(other error, format string, args ...interface{}) Err {
- return Err{
- message: fmt.Sprintf(format, args...),
- cause: Cause(other),
- previous: other,
- }
-}
-
-// Location is the file and line of where the error was most recently
-// created or annotated.
-func (e *Err) Location() (filename string, line int) {
- return e.file, e.line
-}
-
-// Underlying returns the previous error in the error stack, if any. A client
-// should not ever really call this method. It is used to build the error
-// stack and should not be introspected by client calls. Or more
-// specifically, clients should not depend on anything but the `Cause` of an
-// error.
-func (e *Err) Underlying() error {
- return e.previous
-}
-
-// The Cause of an error is the most recent error in the error stack that
-// meets one of these criteria: the original error that was raised; the new
-// error that was passed into the Wrap function; the most recently masked
-// error; or nil if the error itself is considered the Cause. Normally this
-// method is not invoked directly, but instead through the Cause stand alone
-// function.
-func (e *Err) Cause() error {
- return e.cause
-}
-
-// Message returns the message stored with the most recent location. This is
-// the empty string if the most recent call was Trace, or the message stored
-// with Annotate or Mask.
-func (e *Err) Message() string {
- return e.message
-}
-
-// Error implements error.Error.
-func (e *Err) Error() string {
- // We want to walk up the stack of errors showing the annotations
- // as long as the cause is the same.
- err := e.previous
- if !sameError(Cause(err), e.cause) && e.cause != nil {
- err = e.cause
- }
- switch {
- case err == nil:
- return e.message
- case e.message == "":
- return err.Error()
- }
- return fmt.Sprintf("%s: %v", e.message, err)
-}
-
-// Format implements fmt.Formatter
-// When printing errors with %+v it also prints the stack trace.
-// %#v unsurprisingly will print the real underlying type.
-func (e *Err) Format(s fmt.State, verb rune) {
- switch verb {
- case 'v':
- switch {
- case s.Flag('+'):
- fmt.Fprintf(s, "%s", ErrorStack(e))
- return
- case s.Flag('#'):
- // avoid infinite recursion by wrapping e into a type
- // that doesn't implement Formatter.
- fmt.Fprintf(s, "%#v", (*unformatter)(e))
- return
- }
- fallthrough
- case 's':
- fmt.Fprintf(s, "%s", e.Error())
- }
-}
-
-// helper for Format
-type unformatter Err
-
-func (unformatter) Format() { /* break the fmt.Formatter interface */ }
-
-// SetLocation records the source location of the error at callDepth stack
-// frames above the call.
-func (e *Err) SetLocation(callDepth int) {
- _, file, line, _ := runtime.Caller(callDepth + 1)
- e.file = trimGoPath(file)
- e.line = line
-}
-
-// StackTrace returns one string for each location recorded in the stack of
-// errors. The first value is the originating error, with a line for each
-// other annotation or tracing of the error.
-func (e *Err) StackTrace() []string {
- return errorStack(e)
-}
-
-// Ideally we'd have a way to check identity, but deep equals will do.
-func sameError(e1, e2 error) bool {
- return reflect.DeepEqual(e1, e2)
-}
diff --git a/vendor/github.com/juju/errors/errortypes.go b/vendor/github.com/juju/errors/errortypes.go
deleted file mode 100644
index 9b731c44c3d6..000000000000
--- a/vendor/github.com/juju/errors/errortypes.go
+++ /dev/null
@@ -1,309 +0,0 @@
-// Copyright 2014 Canonical Ltd.
-// Licensed under the LGPLv3, see LICENCE file for details.
-
-package errors
-
-import (
- "fmt"
-)
-
-// wrap is a helper to construct an *wrapper.
-func wrap(err error, format, suffix string, args ...interface{}) Err {
- newErr := Err{
- message: fmt.Sprintf(format+suffix, args...),
- previous: err,
- }
- newErr.SetLocation(2)
- return newErr
-}
-
-// notFound represents an error when something has not been found.
-type notFound struct {
- Err
-}
-
-// NotFoundf returns an error which satisfies IsNotFound().
-func NotFoundf(format string, args ...interface{}) error {
- return ¬Found{wrap(nil, format, " not found", args...)}
-}
-
-// NewNotFound returns an error which wraps err that satisfies
-// IsNotFound().
-func NewNotFound(err error, msg string) error {
- return ¬Found{wrap(err, msg, "")}
-}
-
-// IsNotFound reports whether err was created with NotFoundf() or
-// NewNotFound().
-func IsNotFound(err error) bool {
- err = Cause(err)
- _, ok := err.(*notFound)
- return ok
-}
-
-// userNotFound represents an error when an inexistent user is looked up.
-type userNotFound struct {
- Err
-}
-
-// UserNotFoundf returns an error which satisfies IsUserNotFound().
-func UserNotFoundf(format string, args ...interface{}) error {
- return &userNotFound{wrap(nil, format, " user not found", args...)}
-}
-
-// NewUserNotFound returns an error which wraps err and satisfies
-// IsUserNotFound().
-func NewUserNotFound(err error, msg string) error {
- return &userNotFound{wrap(err, msg, "")}
-}
-
-// IsUserNotFound reports whether err was created with UserNotFoundf() or
-// NewUserNotFound().
-func IsUserNotFound(err error) bool {
- err = Cause(err)
- _, ok := err.(*userNotFound)
- return ok
-}
-
-// unauthorized represents an error when an operation is unauthorized.
-type unauthorized struct {
- Err
-}
-
-// Unauthorizedf returns an error which satisfies IsUnauthorized().
-func Unauthorizedf(format string, args ...interface{}) error {
- return &unauthorized{wrap(nil, format, "", args...)}
-}
-
-// NewUnauthorized returns an error which wraps err and satisfies
-// IsUnauthorized().
-func NewUnauthorized(err error, msg string) error {
- return &unauthorized{wrap(err, msg, "")}
-}
-
-// IsUnauthorized reports whether err was created with Unauthorizedf() or
-// NewUnauthorized().
-func IsUnauthorized(err error) bool {
- err = Cause(err)
- _, ok := err.(*unauthorized)
- return ok
-}
-
-// notImplemented represents an error when something is not
-// implemented.
-type notImplemented struct {
- Err
-}
-
-// NotImplementedf returns an error which satisfies IsNotImplemented().
-func NotImplementedf(format string, args ...interface{}) error {
- return ¬Implemented{wrap(nil, format, " not implemented", args...)}
-}
-
-// NewNotImplemented returns an error which wraps err and satisfies
-// IsNotImplemented().
-func NewNotImplemented(err error, msg string) error {
- return ¬Implemented{wrap(err, msg, "")}
-}
-
-// IsNotImplemented reports whether err was created with
-// NotImplementedf() or NewNotImplemented().
-func IsNotImplemented(err error) bool {
- err = Cause(err)
- _, ok := err.(*notImplemented)
- return ok
-}
-
-// alreadyExists represents and error when something already exists.
-type alreadyExists struct {
- Err
-}
-
-// AlreadyExistsf returns an error which satisfies IsAlreadyExists().
-func AlreadyExistsf(format string, args ...interface{}) error {
- return &alreadyExists{wrap(nil, format, " already exists", args...)}
-}
-
-// NewAlreadyExists returns an error which wraps err and satisfies
-// IsAlreadyExists().
-func NewAlreadyExists(err error, msg string) error {
- return &alreadyExists{wrap(err, msg, "")}
-}
-
-// IsAlreadyExists reports whether the error was created with
-// AlreadyExistsf() or NewAlreadyExists().
-func IsAlreadyExists(err error) bool {
- err = Cause(err)
- _, ok := err.(*alreadyExists)
- return ok
-}
-
-// notSupported represents an error when something is not supported.
-type notSupported struct {
- Err
-}
-
-// NotSupportedf returns an error which satisfies IsNotSupported().
-func NotSupportedf(format string, args ...interface{}) error {
- return ¬Supported{wrap(nil, format, " not supported", args...)}
-}
-
-// NewNotSupported returns an error which wraps err and satisfies
-// IsNotSupported().
-func NewNotSupported(err error, msg string) error {
- return ¬Supported{wrap(err, msg, "")}
-}
-
-// IsNotSupported reports whether the error was created with
-// NotSupportedf() or NewNotSupported().
-func IsNotSupported(err error) bool {
- err = Cause(err)
- _, ok := err.(*notSupported)
- return ok
-}
-
-// notValid represents an error when something is not valid.
-type notValid struct {
- Err
-}
-
-// NotValidf returns an error which satisfies IsNotValid().
-func NotValidf(format string, args ...interface{}) error {
- return ¬Valid{wrap(nil, format, " not valid", args...)}
-}
-
-// NewNotValid returns an error which wraps err and satisfies IsNotValid().
-func NewNotValid(err error, msg string) error {
- return ¬Valid{wrap(err, msg, "")}
-}
-
-// IsNotValid reports whether the error was created with NotValidf() or
-// NewNotValid().
-func IsNotValid(err error) bool {
- err = Cause(err)
- _, ok := err.(*notValid)
- return ok
-}
-
-// notProvisioned represents an error when something is not yet provisioned.
-type notProvisioned struct {
- Err
-}
-
-// NotProvisionedf returns an error which satisfies IsNotProvisioned().
-func NotProvisionedf(format string, args ...interface{}) error {
- return ¬Provisioned{wrap(nil, format, " not provisioned", args...)}
-}
-
-// NewNotProvisioned returns an error which wraps err that satisfies
-// IsNotProvisioned().
-func NewNotProvisioned(err error, msg string) error {
- return ¬Provisioned{wrap(err, msg, "")}
-}
-
-// IsNotProvisioned reports whether err was created with NotProvisionedf() or
-// NewNotProvisioned().
-func IsNotProvisioned(err error) bool {
- err = Cause(err)
- _, ok := err.(*notProvisioned)
- return ok
-}
-
-// notAssigned represents an error when something is not yet assigned to
-// something else.
-type notAssigned struct {
- Err
-}
-
-// NotAssignedf returns an error which satisfies IsNotAssigned().
-func NotAssignedf(format string, args ...interface{}) error {
- return ¬Assigned{wrap(nil, format, " not assigned", args...)}
-}
-
-// NewNotAssigned returns an error which wraps err that satisfies
-// IsNotAssigned().
-func NewNotAssigned(err error, msg string) error {
- return ¬Assigned{wrap(err, msg, "")}
-}
-
-// IsNotAssigned reports whether err was created with NotAssignedf() or
-// NewNotAssigned().
-func IsNotAssigned(err error) bool {
- err = Cause(err)
- _, ok := err.(*notAssigned)
- return ok
-}
-
-// badRequest represents an error when a request has bad parameters.
-type badRequest struct {
- Err
-}
-
-// BadRequestf returns an error which satisfies IsBadRequest().
-func BadRequestf(format string, args ...interface{}) error {
- return &badRequest{wrap(nil, format, "", args...)}
-}
-
-// NewBadRequest returns an error which wraps err that satisfies
-// IsBadRequest().
-func NewBadRequest(err error, msg string) error {
- return &badRequest{wrap(err, msg, "")}
-}
-
-// IsBadRequest reports whether err was created with BadRequestf() or
-// NewBadRequest().
-func IsBadRequest(err error) bool {
- err = Cause(err)
- _, ok := err.(*badRequest)
- return ok
-}
-
-// methodNotAllowed represents an error when an HTTP request
-// is made with an inappropriate method.
-type methodNotAllowed struct {
- Err
-}
-
-// MethodNotAllowedf returns an error which satisfies IsMethodNotAllowed().
-func MethodNotAllowedf(format string, args ...interface{}) error {
- return &methodNotAllowed{wrap(nil, format, "", args...)}
-}
-
-// NewMethodNotAllowed returns an error which wraps err that satisfies
-// IsMethodNotAllowed().
-func NewMethodNotAllowed(err error, msg string) error {
- return &methodNotAllowed{wrap(err, msg, "")}
-}
-
-// IsMethodNotAllowed reports whether err was created with MethodNotAllowedf() or
-// NewMethodNotAllowed().
-func IsMethodNotAllowed(err error) bool {
- err = Cause(err)
- _, ok := err.(*methodNotAllowed)
- return ok
-}
-
-// forbidden represents an error when a request cannot be completed because of
-// missing privileges
-type forbidden struct {
- Err
-}
-
-// Forbiddenf returns an error which satistifes IsForbidden()
-func Forbiddenf(format string, args ...interface{}) error {
- return &forbidden{wrap(nil, format, "", args...)}
-}
-
-// NewForbidden returns an error which wraps err that satisfies
-// IsForbidden().
-func NewForbidden(err error, msg string) error {
- return &forbidden{wrap(err, msg, "")}
-}
-
-// IsForbidden reports whether err was created with Forbiddenf() or
-// NewForbidden().
-func IsForbidden(err error) bool {
- err = Cause(err)
- _, ok := err.(*forbidden)
- return ok
-}
diff --git a/vendor/github.com/juju/errors/functions.go b/vendor/github.com/juju/errors/functions.go
deleted file mode 100644
index f86b09b2dbad..000000000000
--- a/vendor/github.com/juju/errors/functions.go
+++ /dev/null
@@ -1,330 +0,0 @@
-// Copyright 2014 Canonical Ltd.
-// Licensed under the LGPLv3, see LICENCE file for details.
-
-package errors
-
-import (
- "fmt"
- "strings"
-)
-
-// New is a drop in replacement for the standard library errors module that records
-// the location that the error is created.
-//
-// For example:
-// return errors.New("validation failed")
-//
-func New(message string) error {
- err := &Err{message: message}
- err.SetLocation(1)
- return err
-}
-
-// Errorf creates a new annotated error and records the location that the
-// error is created. This should be a drop in replacement for fmt.Errorf.
-//
-// For example:
-// return errors.Errorf("validation failed: %s", message)
-//
-func Errorf(format string, args ...interface{}) error {
- err := &Err{message: fmt.Sprintf(format, args...)}
- err.SetLocation(1)
- return err
-}
-
-// Trace adds the location of the Trace call to the stack. The Cause of the
-// resulting error is the same as the error parameter. If the other error is
-// nil, the result will be nil.
-//
-// For example:
-// if err := SomeFunc(); err != nil {
-// return errors.Trace(err)
-// }
-//
-func Trace(other error) error {
- if other == nil {
- return nil
- }
- err := &Err{previous: other, cause: Cause(other)}
- err.SetLocation(1)
- return err
-}
-
-// Annotate is used to add extra context to an existing error. The location of
-// the Annotate call is recorded with the annotations. The file, line and
-// function are also recorded.
-//
-// For example:
-// if err := SomeFunc(); err != nil {
-// return errors.Annotate(err, "failed to frombulate")
-// }
-//
-func Annotate(other error, message string) error {
- if other == nil {
- return nil
- }
- err := &Err{
- previous: other,
- cause: Cause(other),
- message: message,
- }
- err.SetLocation(1)
- return err
-}
-
-// Annotatef is used to add extra context to an existing error. The location of
-// the Annotate call is recorded with the annotations. The file, line and
-// function are also recorded.
-//
-// For example:
-// if err := SomeFunc(); err != nil {
-// return errors.Annotatef(err, "failed to frombulate the %s", arg)
-// }
-//
-func Annotatef(other error, format string, args ...interface{}) error {
- if other == nil {
- return nil
- }
- err := &Err{
- previous: other,
- cause: Cause(other),
- message: fmt.Sprintf(format, args...),
- }
- err.SetLocation(1)
- return err
-}
-
-// DeferredAnnotatef annotates the given error (when it is not nil) with the given
-// format string and arguments (like fmt.Sprintf). If *err is nil, DeferredAnnotatef
-// does nothing. This method is used in a defer statement in order to annotate any
-// resulting error with the same message.
-//
-// For example:
-//
-// defer DeferredAnnotatef(&err, "failed to frombulate the %s", arg)
-//
-func DeferredAnnotatef(err *error, format string, args ...interface{}) {
- if *err == nil {
- return
- }
- newErr := &Err{
- message: fmt.Sprintf(format, args...),
- cause: Cause(*err),
- previous: *err,
- }
- newErr.SetLocation(1)
- *err = newErr
-}
-
-// Wrap changes the Cause of the error. The location of the Wrap call is also
-// stored in the error stack.
-//
-// For example:
-// if err := SomeFunc(); err != nil {
-// newErr := &packageError{"more context", private_value}
-// return errors.Wrap(err, newErr)
-// }
-//
-func Wrap(other, newDescriptive error) error {
- err := &Err{
- previous: other,
- cause: newDescriptive,
- }
- err.SetLocation(1)
- return err
-}
-
-// Wrapf changes the Cause of the error, and adds an annotation. The location
-// of the Wrap call is also stored in the error stack.
-//
-// For example:
-// if err := SomeFunc(); err != nil {
-// return errors.Wrapf(err, simpleErrorType, "invalid value %q", value)
-// }
-//
-func Wrapf(other, newDescriptive error, format string, args ...interface{}) error {
- err := &Err{
- message: fmt.Sprintf(format, args...),
- previous: other,
- cause: newDescriptive,
- }
- err.SetLocation(1)
- return err
-}
-
-// Mask masks the given error with the given format string and arguments (like
-// fmt.Sprintf), returning a new error that maintains the error stack, but
-// hides the underlying error type. The error string still contains the full
-// annotations. If you want to hide the annotations, call Wrap.
-func Maskf(other error, format string, args ...interface{}) error {
- if other == nil {
- return nil
- }
- err := &Err{
- message: fmt.Sprintf(format, args...),
- previous: other,
- }
- err.SetLocation(1)
- return err
-}
-
-// Mask hides the underlying error type, and records the location of the masking.
-func Mask(other error) error {
- if other == nil {
- return nil
- }
- err := &Err{
- previous: other,
- }
- err.SetLocation(1)
- return err
-}
-
-// Cause returns the cause of the given error. This will be either the
-// original error, or the result of a Wrap or Mask call.
-//
-// Cause is the usual way to diagnose errors that may have been wrapped by
-// the other errors functions.
-func Cause(err error) error {
- var diag error
- if err, ok := err.(causer); ok {
- diag = err.Cause()
- }
- if diag != nil {
- return diag
- }
- return err
-}
-
-type causer interface {
- Cause() error
-}
-
-type wrapper interface {
- // Message returns the top level error message,
- // not including the message from the Previous
- // error.
- Message() string
-
- // Underlying returns the Previous error, or nil
- // if there is none.
- Underlying() error
-}
-
-type locationer interface {
- Location() (string, int)
-}
-
-var (
- _ wrapper = (*Err)(nil)
- _ locationer = (*Err)(nil)
- _ causer = (*Err)(nil)
-)
-
-// Details returns information about the stack of errors wrapped by err, in
-// the format:
-//
-// [{filename:99: error one} {otherfile:55: cause of error one}]
-//
-// This is a terse alternative to ErrorStack as it returns a single line.
-func Details(err error) string {
- if err == nil {
- return "[]"
- }
- var s []byte
- s = append(s, '[')
- for {
- s = append(s, '{')
- if err, ok := err.(locationer); ok {
- file, line := err.Location()
- if file != "" {
- s = append(s, fmt.Sprintf("%s:%d", file, line)...)
- s = append(s, ": "...)
- }
- }
- if cerr, ok := err.(wrapper); ok {
- s = append(s, cerr.Message()...)
- err = cerr.Underlying()
- } else {
- s = append(s, err.Error()...)
- err = nil
- }
- s = append(s, '}')
- if err == nil {
- break
- }
- s = append(s, ' ')
- }
- s = append(s, ']')
- return string(s)
-}
-
-// ErrorStack returns a string representation of the annotated error. If the
-// error passed as the parameter is not an annotated error, the result is
-// simply the result of the Error() method on that error.
-//
-// If the error is an annotated error, a multi-line string is returned where
-// each line represents one entry in the annotation stack. The full filename
-// from the call stack is used in the output.
-//
-// first error
-// github.com/juju/errors/annotation_test.go:193:
-// github.com/juju/errors/annotation_test.go:194: annotation
-// github.com/juju/errors/annotation_test.go:195:
-// github.com/juju/errors/annotation_test.go:196: more context
-// github.com/juju/errors/annotation_test.go:197:
-func ErrorStack(err error) string {
- return strings.Join(errorStack(err), "\n")
-}
-
-func errorStack(err error) []string {
- if err == nil {
- return nil
- }
-
- // We want the first error first
- var lines []string
- for {
- var buff []byte
- if err, ok := err.(locationer); ok {
- file, line := err.Location()
- // Strip off the leading GOPATH/src path elements.
- file = trimGoPath(file)
- if file != "" {
- buff = append(buff, fmt.Sprintf("%s:%d", file, line)...)
- buff = append(buff, ": "...)
- }
- }
- if cerr, ok := err.(wrapper); ok {
- message := cerr.Message()
- buff = append(buff, message...)
- // If there is a cause for this error, and it is different to the cause
- // of the underlying error, then output the error string in the stack trace.
- var cause error
- if err1, ok := err.(causer); ok {
- cause = err1.Cause()
- }
- err = cerr.Underlying()
- if cause != nil && !sameError(Cause(err), cause) {
- if message != "" {
- buff = append(buff, ": "...)
- }
- buff = append(buff, cause.Error()...)
- }
- } else {
- buff = append(buff, err.Error()...)
- err = nil
- }
- lines = append(lines, string(buff))
- if err == nil {
- break
- }
- }
- // reverse the lines to get the original error, which was at the end of
- // the list, back to the start.
- var result []string
- for i := len(lines); i > 0; i-- {
- result = append(result, lines[i-1])
- }
- return result
-}
diff --git a/vendor/github.com/juju/errors/path.go b/vendor/github.com/juju/errors/path.go
deleted file mode 100644
index a7b726ab094c..000000000000
--- a/vendor/github.com/juju/errors/path.go
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2013, 2014 Canonical Ltd.
-// Licensed under the LGPLv3, see LICENCE file for details.
-
-package errors
-
-import (
- "runtime"
- "strings"
-)
-
-// prefixSize is used internally to trim the user specific path from the
-// front of the returned filenames from the runtime call stack.
-var prefixSize int
-
-// goPath is the deduced path based on the location of this file as compiled.
-var goPath string
-
-func init() {
- _, file, _, ok := runtime.Caller(0)
- if file == "?" {
- return
- }
- if ok {
- // We know that the end of the file should be:
- // github.com/juju/errors/path.go
- size := len(file)
- suffix := len("github.com/juju/errors/path.go")
- goPath = file[:size-suffix]
- prefixSize = len(goPath)
- }
-}
-
-func trimGoPath(filename string) string {
- if strings.HasPrefix(filename, goPath) {
- return filename[prefixSize:]
- }
- return filename
-}
diff --git a/vendor/github.com/pkg/errors/LICENSE b/vendor/github.com/pkg/errors/LICENSE
new file mode 100644
index 000000000000..835ba3e755ce
--- /dev/null
+++ b/vendor/github.com/pkg/errors/LICENSE
@@ -0,0 +1,23 @@
+Copyright (c) 2015, Dave Cheney
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/github.com/pkg/errors/errors.go b/vendor/github.com/pkg/errors/errors.go
new file mode 100644
index 000000000000..842ee80456db
--- /dev/null
+++ b/vendor/github.com/pkg/errors/errors.go
@@ -0,0 +1,269 @@
+// Package errors provides simple error handling primitives.
+//
+// The traditional error handling idiom in Go is roughly akin to
+//
+// if err != nil {
+// return err
+// }
+//
+// which applied recursively up the call stack results in error reports
+// without context or debugging information. The errors package allows
+// programmers to add context to the failure path in their code in a way
+// that does not destroy the original value of the error.
+//
+// Adding context to an error
+//
+// The errors.Wrap function returns a new error that adds context to the
+// original error by recording a stack trace at the point Wrap is called,
+// and the supplied message. For example
+//
+// _, err := ioutil.ReadAll(r)
+// if err != nil {
+// return errors.Wrap(err, "read failed")
+// }
+//
+// If additional control is required the errors.WithStack and errors.WithMessage
+// functions destructure errors.Wrap into its component operations of annotating
+// an error with a stack trace and an a message, respectively.
+//
+// Retrieving the cause of an error
+//
+// Using errors.Wrap constructs a stack of errors, adding context to the
+// preceding error. Depending on the nature of the error it may be necessary
+// to reverse the operation of errors.Wrap to retrieve the original error
+// for inspection. Any error value which implements this interface
+//
+// type causer interface {
+// Cause() error
+// }
+//
+// can be inspected by errors.Cause. errors.Cause will recursively retrieve
+// the topmost error which does not implement causer, which is assumed to be
+// the original cause. For example:
+//
+// switch err := errors.Cause(err).(type) {
+// case *MyError:
+// // handle specifically
+// default:
+// // unknown error
+// }
+//
+// causer interface is not exported by this package, but is considered a part
+// of stable public API.
+//
+// Formatted printing of errors
+//
+// All error values returned from this package implement fmt.Formatter and can
+// be formatted by the fmt package. The following verbs are supported
+//
+// %s print the error. If the error has a Cause it will be
+// printed recursively
+// %v see %s
+// %+v extended format. Each Frame of the error's StackTrace will
+// be printed in detail.
+//
+// Retrieving the stack trace of an error or wrapper
+//
+// New, Errorf, Wrap, and Wrapf record a stack trace at the point they are
+// invoked. This information can be retrieved with the following interface.
+//
+// type stackTracer interface {
+// StackTrace() errors.StackTrace
+// }
+//
+// Where errors.StackTrace is defined as
+//
+// type StackTrace []Frame
+//
+// The Frame type represents a call site in the stack trace. Frame supports
+// the fmt.Formatter interface that can be used for printing information about
+// the stack trace of this error. For example:
+//
+// if err, ok := err.(stackTracer); ok {
+// for _, f := range err.StackTrace() {
+// fmt.Printf("%+s:%d", f)
+// }
+// }
+//
+// stackTracer interface is not exported by this package, but is considered a part
+// of stable public API.
+//
+// See the documentation for Frame.Format for more details.
+package errors
+
+import (
+ "fmt"
+ "io"
+)
+
+// New returns an error with the supplied message.
+// New also records the stack trace at the point it was called.
+func New(message string) error {
+ return &fundamental{
+ msg: message,
+ stack: callers(),
+ }
+}
+
+// Errorf formats according to a format specifier and returns the string
+// as a value that satisfies error.
+// Errorf also records the stack trace at the point it was called.
+func Errorf(format string, args ...interface{}) error {
+ return &fundamental{
+ msg: fmt.Sprintf(format, args...),
+ stack: callers(),
+ }
+}
+
+// fundamental is an error that has a message and a stack, but no caller.
+type fundamental struct {
+ msg string
+ *stack
+}
+
+func (f *fundamental) Error() string { return f.msg }
+
+func (f *fundamental) Format(s fmt.State, verb rune) {
+ switch verb {
+ case 'v':
+ if s.Flag('+') {
+ io.WriteString(s, f.msg)
+ f.stack.Format(s, verb)
+ return
+ }
+ fallthrough
+ case 's':
+ io.WriteString(s, f.msg)
+ case 'q':
+ fmt.Fprintf(s, "%q", f.msg)
+ }
+}
+
+// WithStack annotates err with a stack trace at the point WithStack was called.
+// If err is nil, WithStack returns nil.
+func WithStack(err error) error {
+ if err == nil {
+ return nil
+ }
+ return &withStack{
+ err,
+ callers(),
+ }
+}
+
+type withStack struct {
+ error
+ *stack
+}
+
+func (w *withStack) Cause() error { return w.error }
+
+func (w *withStack) Format(s fmt.State, verb rune) {
+ switch verb {
+ case 'v':
+ if s.Flag('+') {
+ fmt.Fprintf(s, "%+v", w.Cause())
+ w.stack.Format(s, verb)
+ return
+ }
+ fallthrough
+ case 's':
+ io.WriteString(s, w.Error())
+ case 'q':
+ fmt.Fprintf(s, "%q", w.Error())
+ }
+}
+
+// Wrap returns an error annotating err with a stack trace
+// at the point Wrap is called, and the supplied message.
+// If err is nil, Wrap returns nil.
+func Wrap(err error, message string) error {
+ if err == nil {
+ return nil
+ }
+ err = &withMessage{
+ cause: err,
+ msg: message,
+ }
+ return &withStack{
+ err,
+ callers(),
+ }
+}
+
+// Wrapf returns an error annotating err with a stack trace
+// at the point Wrapf is call, and the format specifier.
+// If err is nil, Wrapf returns nil.
+func Wrapf(err error, format string, args ...interface{}) error {
+ if err == nil {
+ return nil
+ }
+ err = &withMessage{
+ cause: err,
+ msg: fmt.Sprintf(format, args...),
+ }
+ return &withStack{
+ err,
+ callers(),
+ }
+}
+
+// WithMessage annotates err with a new message.
+// If err is nil, WithMessage returns nil.
+func WithMessage(err error, message string) error {
+ if err == nil {
+ return nil
+ }
+ return &withMessage{
+ cause: err,
+ msg: message,
+ }
+}
+
+type withMessage struct {
+ cause error
+ msg string
+}
+
+func (w *withMessage) Error() string { return w.msg + ": " + w.cause.Error() }
+func (w *withMessage) Cause() error { return w.cause }
+
+func (w *withMessage) Format(s fmt.State, verb rune) {
+ switch verb {
+ case 'v':
+ if s.Flag('+') {
+ fmt.Fprintf(s, "%+v\n", w.Cause())
+ io.WriteString(s, w.msg)
+ return
+ }
+ fallthrough
+ case 's', 'q':
+ io.WriteString(s, w.Error())
+ }
+}
+
+// Cause returns the underlying cause of the error, if possible.
+// An error value has a cause if it implements the following
+// interface:
+//
+// type causer interface {
+// Cause() error
+// }
+//
+// If the error does not implement Cause, the original error will
+// be returned. If the error is nil, nil will be returned without further
+// investigation.
+func Cause(err error) error {
+ type causer interface {
+ Cause() error
+ }
+
+ for err != nil {
+ cause, ok := err.(causer)
+ if !ok {
+ break
+ }
+ err = cause.Cause()
+ }
+ return err
+}
diff --git a/vendor/github.com/pkg/errors/stack.go b/vendor/github.com/pkg/errors/stack.go
new file mode 100644
index 000000000000..6b1f2891a5ac
--- /dev/null
+++ b/vendor/github.com/pkg/errors/stack.go
@@ -0,0 +1,178 @@
+package errors
+
+import (
+ "fmt"
+ "io"
+ "path"
+ "runtime"
+ "strings"
+)
+
+// Frame represents a program counter inside a stack frame.
+type Frame uintptr
+
+// pc returns the program counter for this frame;
+// multiple frames may have the same PC value.
+func (f Frame) pc() uintptr { return uintptr(f) - 1 }
+
+// file returns the full path to the file that contains the
+// function for this Frame's pc.
+func (f Frame) file() string {
+ fn := runtime.FuncForPC(f.pc())
+ if fn == nil {
+ return "unknown"
+ }
+ file, _ := fn.FileLine(f.pc())
+ return file
+}
+
+// line returns the line number of source code of the
+// function for this Frame's pc.
+func (f Frame) line() int {
+ fn := runtime.FuncForPC(f.pc())
+ if fn == nil {
+ return 0
+ }
+ _, line := fn.FileLine(f.pc())
+ return line
+}
+
+// Format formats the frame according to the fmt.Formatter interface.
+//
+// %s source file
+// %d source line
+// %n function name
+// %v equivalent to %s:%d
+//
+// Format accepts flags that alter the printing of some verbs, as follows:
+//
+// %+s path of source file relative to the compile time GOPATH
+// %+v equivalent to %+s:%d
+func (f Frame) Format(s fmt.State, verb rune) {
+ switch verb {
+ case 's':
+ switch {
+ case s.Flag('+'):
+ pc := f.pc()
+ fn := runtime.FuncForPC(pc)
+ if fn == nil {
+ io.WriteString(s, "unknown")
+ } else {
+ file, _ := fn.FileLine(pc)
+ fmt.Fprintf(s, "%s\n\t%s", fn.Name(), file)
+ }
+ default:
+ io.WriteString(s, path.Base(f.file()))
+ }
+ case 'd':
+ fmt.Fprintf(s, "%d", f.line())
+ case 'n':
+ name := runtime.FuncForPC(f.pc()).Name()
+ io.WriteString(s, funcname(name))
+ case 'v':
+ f.Format(s, 's')
+ io.WriteString(s, ":")
+ f.Format(s, 'd')
+ }
+}
+
+// StackTrace is stack of Frames from innermost (newest) to outermost (oldest).
+type StackTrace []Frame
+
+func (st StackTrace) Format(s fmt.State, verb rune) {
+ switch verb {
+ case 'v':
+ switch {
+ case s.Flag('+'):
+ for _, f := range st {
+ fmt.Fprintf(s, "\n%+v", f)
+ }
+ case s.Flag('#'):
+ fmt.Fprintf(s, "%#v", []Frame(st))
+ default:
+ fmt.Fprintf(s, "%v", []Frame(st))
+ }
+ case 's':
+ fmt.Fprintf(s, "%s", []Frame(st))
+ }
+}
+
+// stack represents a stack of program counters.
+type stack []uintptr
+
+func (s *stack) Format(st fmt.State, verb rune) {
+ switch verb {
+ case 'v':
+ switch {
+ case st.Flag('+'):
+ for _, pc := range *s {
+ f := Frame(pc)
+ fmt.Fprintf(st, "\n%+v", f)
+ }
+ }
+ }
+}
+
+func (s *stack) StackTrace() StackTrace {
+ f := make([]Frame, len(*s))
+ for i := 0; i < len(f); i++ {
+ f[i] = Frame((*s)[i])
+ }
+ return f
+}
+
+func callers() *stack {
+ const depth = 32
+ var pcs [depth]uintptr
+ n := runtime.Callers(3, pcs[:])
+ var st stack = pcs[0:n]
+ return &st
+}
+
+// funcname removes the path prefix component of a function's name reported by func.Name().
+func funcname(name string) string {
+ i := strings.LastIndex(name, "/")
+ name = name[i+1:]
+ i = strings.Index(name, ".")
+ return name[i+1:]
+}
+
+func trimGOPATH(name, file string) string {
+ // Here we want to get the source file path relative to the compile time
+ // GOPATH. As of Go 1.6.x there is no direct way to know the compiled
+ // GOPATH at runtime, but we can infer the number of path segments in the
+ // GOPATH. We note that fn.Name() returns the function name qualified by
+ // the import path, which does not include the GOPATH. Thus we can trim
+ // segments from the beginning of the file path until the number of path
+ // separators remaining is one more than the number of path separators in
+ // the function name. For example, given:
+ //
+ // GOPATH /home/user
+ // file /home/user/src/pkg/sub/file.go
+ // fn.Name() pkg/sub.Type.Method
+ //
+ // We want to produce:
+ //
+ // pkg/sub/file.go
+ //
+ // From this we can easily see that fn.Name() has one less path separator
+ // than our desired output. We count separators from the end of the file
+ // path until it finds two more than in the function name and then move
+ // one character forward to preserve the initial path segment without a
+ // leading separator.
+ const sep = "/"
+ goal := strings.Count(name, sep) + 2
+ i := len(file)
+ for n := 0; n < goal; n++ {
+ i = strings.LastIndex(file[:i], sep)
+ if i == -1 {
+ // not enough separators found, set i so that the slice expression
+ // below leaves file unmodified
+ i = -len(sep)
+ break
+ }
+ }
+ // get back to 0 or trim the leading separator
+ file = file[i+len(sep):]
+ return file
+}