Repository: magefile/mage
Pull request #26 (2017-10-02 02:21:57)

Helpers galore
This commit adds helper functions that should be commonly needed
by many magefiles. It includes command execution handlers as well
as error handlers.

This commit also removes the only two non-stdlib dependencies in
the codebase.  Since mage will likely be vendored into a repo,
it would be nice to avoid cluttering the vendor directory with 
dependencies that are only for the build script.

natefinch: This should land soon. Just testing out the API surface by converting some makefiles to mage. 

Patch:
diff --git a/Gopkg.lock b/Gopkg.lock
index d13dfdf..bef2d00 100644
--- a/Gopkg.lock
+++ b/Gopkg.lock
@@ -1,21 +1,9 @@
 # This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
 
 
-[[projects]]
-  name = "github.com/google/go-cmp"
-  packages = ["cmp","cmp/internal/diff","cmp/internal/function","cmp/internal/value"]
-  revision = "8099a9787ce5dc5984ed879a3bda47dc730a8e97"
-  version = "v0.1.0"
-
-[[projects]]
-  name = "github.com/pkg/errors"
-  packages = ["."]
-  revision = "645ef00459ed84a119197bfb8d8205042c6df63d"
-  version = "v0.8.0"
-
 [solve-meta]
   analyzer-name = "dep"
   analyzer-version = 1
-  inputs-digest = "d4510f3f4485537cfc975602697f757fa5ae57c6ea1945ee1648d1ec11c9f575"
+  inputs-digest = "ab4fef131ee828e96ba67d31a7d690bd5f2f42040c6766b1b12fe856f87e0ff7"
   solver-name = "gps-cdcl"
   solver-version = 1
diff --git a/Gopkg.toml b/Gopkg.toml
index e8ca6fa..9425a54 100644
--- a/Gopkg.toml
+++ b/Gopkg.toml
@@ -20,11 +20,3 @@
 #  name = "github.com/x/y"
 #  version = "2.4.0"
 
-
-[[constraint]]
-  name = "github.com/google/go-cmp"
-  version = "0.1.0"
-
-[[constraint]]
-  name = "github.com/pkg/errors"
-  version = "0.8.0"
diff --git a/mage/main.go b/mage/main.go
index 0dbd37d..1875417 100644
--- a/mage/main.go
+++ b/mage/main.go
@@ -2,6 +2,7 @@ package mage
 
 import (
 	"crypto/sha1"
+	"errors"
 	"flag"
 	"fmt"
 	"io"
@@ -15,9 +16,8 @@ import (
 	"syscall"
 	"text/template"
 
-	"github.com/pkg/errors"
-
 	"github.com/magefile/mage/build"
+	"github.com/magefile/mage/mg"
 	"github.com/magefile/mage/parse"
 )
 
@@ -149,11 +149,11 @@ func magefiles() ([]string, error) {
 
 func compile(out string, info *parse.PkgInfo, gofiles []string) error {
 	if err := os.MkdirAll(filepath.Dir(out), 0700); err != nil {
-		return errors.WithMessage(err, "can't create cachedir")
+		return fmt.Errorf("can't create cachedir: %v", err)
 	}
 	f, err := os.Create(mainfile)
 	if err != nil {
-		return errors.WithMessage(err, "can't create mainfile")
+		return fmt.Errorf("can't create mainfile: %v", err)
 	}
 	if !keep {
 		defer os.Remove(mainfile)
@@ -168,7 +168,7 @@ func compile(out string, info *parse.PkgInfo, gofiles []string) error {
 	data.DefaultError = info.DefaultIsError
 
 	if err := output.Execute(f, data); err != nil {
-		return errors.WithMessage(err, "can't execute mainfile template")
+		return fmt.Errorf("can't execute mainfile template: %v", err)
 	}
 	// close is idenmpotent, so this is ok
 	f.Close()
@@ -198,8 +198,8 @@ func ExeName(files []string) (string, error) {
 	sort.Strings(hashes)
 	hash := sha1.Sum([]byte(strings.Join(hashes, "") + mageVer))
 	filename := fmt.Sprintf("%x", hash)
-	dir := confDir()
-	out := filepath.Join(dir, filename)
+
+	out := filepath.Join(mg.CacheDir(), filename)
 	if runtime.GOOS == "windows" {
 		out += ".exe"
 	}
@@ -209,44 +209,26 @@ func ExeName(files []string) (string, error) {
 func hashFile(fn string) (string, error) {
 	f, err := os.Open(fn)
 	if err != nil {
-		return "", errors.WithMessage(err, "can't open input file")
+		return "", fmt.Errorf("can't open input file: %v", err)
 	}
 	defer f.Close()
 
 	h := sha1.New()
 	if _, err := io.Copy(h, f); err != nil {
-		return "", errors.WithMessage(err, "can't write data to hash")
+		return "", fmt.Errorf("can't write data to hash: %v", err)
 	}
 	return fmt.Sprintf("%x", h.Sum(nil)), nil
 }
 
-// CacheEnv is the environment variable that users may set to change the
-// location where mage stores its compiled binaries.
-const CacheEnv = "MAGEFILE_CACHE"
-
-// confDir returns the default gorram configuration directory.
-func confDir() string {
-	d := os.Getenv(CacheEnv)
-	if d != "" {
-		return d
-	}
-	switch runtime.GOOS {
-	case "windows":
-		return filepath.Join(os.Getenv("HOMEDRIVE"), os.Getenv("HOMEPATH"), "magoo")
-	default:
-		return filepath.Join(os.Getenv("HOME"), ".magefile")
-	}
-}
-
 func generateInit() error {
 	f, err := os.Create(initFile)
 	if err != nil {
-		return errors.WithMessage(err, "could not create mage template")
+		return fmt.Errorf("could not create mage template: %v", err)
 	}
 	defer f.Close()
 
 	if err := initOutput.Execute(f, nil); err != nil {
-		return errors.WithMessage(err, "can't execute magefile template")
+		return fmt.Errorf("can't execute magefile template: %v", err)
 	}
 
 	return nil
diff --git a/mg/deps.go b/mg/deps.go
index 9685acb..4284c23 100644
--- a/mg/deps.go
+++ b/mg/deps.go
@@ -6,8 +6,6 @@ import (
 	"runtime"
 	"strings"
 	"sync"
-
-	"github.com/pkg/errors"
 )
 
 type onceMap struct {
@@ -43,7 +41,7 @@ func Deps(fns ...interface{}) {
 		case func(), func() error:
 			// ok
 		default:
-			panic(errors.Errorf("Invalid type for dependent function: %T. Dependencies must be func() or func() error", f))
+			panic(fmt.Errorf("Invalid type for dependent function: %T. Dependencies must be func() or func() error", f))
 		}
 	}
 	mu := &sync.Mutex{}
diff --git a/mg/errors.go b/mg/errors.go
index b8f9c57..06a8690 100644
--- a/mg/errors.go
+++ b/mg/errors.go
@@ -1,9 +1,8 @@
 package mg
 
 import (
+	"errors"
 	"fmt"
-
-	"github.com/pkg/errors"
 )
 
 type fatalErr struct {
@@ -33,7 +32,7 @@ func Fatal(code int, args ...interface{}) error {
 func Fatalf(code int, format string, args ...interface{}) error {
 	return fatalErr{
 		code:  code,
-		error: errors.Errorf(format, args...),
+		error: fmt.Errorf(format, args...),
 	}
 }
 
diff --git a/mg/runtime.go b/mg/runtime.go
new file mode 100644
index 0000000..8b99613
--- /dev/null
+++ b/mg/runtime.go
@@ -0,0 +1,36 @@
+package mg
+
+import (
+	"os"
+	"path/filepath"
+	"runtime"
+)
+
+// CacheEnv is the environment variable that users may set to change the
+// location where mage stores its compiled binaries.
+const CacheEnv = "MAGEFILE_CACHE"
+
+// verboseEnv is the environment variable that indicates the user requested
+// verbose mode when running a magefile.
+const verboseEnv = "MAGEFILE_VERBOSE"
+
+// Verbose reports whether a magefile was run with the verbose flag.
+func Verbose() bool {
+	return os.Getenv(verboseEnv) != ""
+}
+
+// CacheDir returns the directory where mage caches compiled binaries.  It
+// defaults to $HOME/.magefile, but may be overridden by the MAGEFILE_CACHE
+// environment variable.
+func CacheDir() string {
+	d := os.Getenv(CacheEnv)
+	if d != "" {
+		return d
+	}
+	switch runtime.GOOS {
+	case "windows":
+		return filepath.Join(os.Getenv("HOMEDRIVE"), os.Getenv("HOMEPATH"), "magefile")
+	default:
+		return filepath.Join(os.Getenv("HOME"), ".magefile")
+	}
+}
diff --git a/parse/parse.go b/parse/parse.go
index a9be5be..c7249ed 100644
--- a/parse/parse.go
+++ b/parse/parse.go
@@ -10,8 +10,6 @@ import (
 	"log"
 	"os"
 	"strings"
-
-	"github.com/pkg/errors"
 )
 
 type PkgInfo struct {
@@ -107,7 +105,7 @@ func getPackage(path string, files []string, fset *token.FileSet) (*ast.Package,
 
 	pkgs, err := parser.ParseDir(fset, path, filter, parser.ParseComments)
 	if err != nil {
-		return nil, errors.WithStack(err)
+		return nil, err
 	}
 
 	for name, pkg := range pkgs {
@@ -135,7 +133,7 @@ func makeInfo(dir string, fset *token.FileSet, files map[string]*ast.File) (type
 	}
 
 	_, err := cfg.Check(dir, fset, fs, &info)
-	return info, errors.WithStack(err)
+	return info, err
 }
 
 // errorOrVoid filters the list of functions to only those that return only an
diff --git a/sh/cmd.go b/sh/cmd.go
new file mode 100644
index 0000000..9ac1b4e
--- /dev/null
+++ b/sh/cmd.go
@@ -0,0 +1,158 @@
+package sh
+
+import (
+	"bytes"
+	"fmt"
+	"io"
+	"log"
+	"os"
+	"os/exec"
+	"strings"
+
+	"github.com/magefile/mage/mg"
+)
+
+// RunCmd returns a function that will call Run with the given command. This is
+// useful for creating command aliases to make your scripts easier to read, like
+// this:
+//
+//  // in a helper file somewhere
+//  var g0 = sh.RunCmd("go")  // go is a keyword :(
+//
+//  // somewhere in your main code
+//	if err := g0("install", "github.com/gohugo/hugo"); err != nil {
+//		return err
+//  }
+//
+// Args passed to command get baked in as args to the command when you run it.
+// Any args passed in when you run the returned function will be appended to the
+// original args.  For example, this is equivalent to the above:
+//
+//  var goInstall = sh.RunCmd("go", "install") goInstall("github.com/gohugo/hugo")
+//
+// RunCmd uses Exec underneath, so see those docs for more details.
+func RunCmd(cmd string, args ...string) func(args ...string) error {
+	return func(args2 ...string) error {
+		return Run(cmd, append(args, args2...)...)
+	}
+}
+
+// OutCmd is like RunCmd except the command returns the output of the
+// command.
+func OutCmd(cmd string, args ...string) func(args ...string) (string, error) {
+	return func(args2 ...string) (string, error) {
+		return Output(cmd, append(args, args2...)...)
+	}
+}
+
+// Run is like RunWith, but doesn't specify any environment variables.
+func Run(cmd string, args ...string) error {
+	return RunWith(nil, cmd, args...)
+}
+
+// RunWith runs the given command, directing stderr to this program's stderr and
+// printing stdout to stdout if mage was run with -v.  It adds adds env to the
+// environment variables for the command being run. Environment variables should
+// be in the format name=value.
+func RunWith(env map[string]string, cmd string, args ...string) error {
+	var output io.Writer
+	if mg.Verbose() {
+		output = os.Stdout
+	}
+	_, err := Exec(env, output, cmd, args...)
+	return err
+}
+
+// Output runs the command and returns the text from stdout.
+func Output(cmd string, args ...string) (string, error) {
+	buf := &bytes.Buffer{}
+	_, err := Exec(nil, buf, cmd, args...)
+	return strings.TrimSuffix(buf.String(), "\n"), err
+}
+
+// OutputWith is like RunWith, ubt returns what is written to stdout.
+func OutputWith(env map[string]string, cmd string, args ...string) (string, error) {
+	buf := &bytes.Buffer{}
+	_, err := Exec(env, buf, cmd, args...)
+	return strings.TrimSuffix(buf.String(), "\n"), err
+}
+
+// Exec executes the command, piping its stderr to mage's stderr and
+// piping its stdout to the given writer. If the command fails, it will return
+// an error that, if returned from a target or mg.Deps call, will cause mage to
+// exit with the same code as the command failed with.  Env is a list of
+// environment variables to set when running the command, these override the
+// current environment variables set (which are also passed to the command). cmd
+// and args may include references to environment variables in $FOO format, in
+// which case these will be expanded before the command is run.
+//
+// Ran reports if the command ran (rather than was not found or not executable).
+// Code reports the exit code the command returned if it ran. If err == nil, ran
+// is always true and code is always 0.
+func Exec(env map[string]string, stdout io.Writer, cmd string, args ...string) (ran bool, err error) {
+	expand := func(s string) string {
+		s2, ok := env[s]
+		if ok {
+			return s2
+		}
+		return os.Getenv(s)
+	}
+	cmd = os.Expand(cmd, expand)
+	for i := range args {
+		args[i] = os.Expand(args[i], expand)
+	}
+	ran, code, err := run(env, stdout, cmd, args...)
+	if err == nil {
+		return true, nil
+	}
+	if ran {
+		return ran, mg.Fatalf(code, `running "%s %s" failed with exit code %d`, cmd, strings.Join(args, " "), code)
+	}
+	return ran, fmt.Errorf(`failed to run "%s %s: %v"`, cmd, strings.Join(args, " "), err)
+}
+
+func run(env map[string]string, stdout io.Writer, cmd string, args ...string) (ran bool, code int, err error) {
+	c := exec.Command(cmd, args...)
+	c.Env = os.Environ()
+	for k, v := range env {
+		c.Env = append(c.Env, k+"="+v)
+	}
+	c.Stderr = os.Stderr
+	c.Stdout = stdout
+	log.Println("exec:", cmd, strings.Join(args, " "))
+	err = c.Run()
+	return cmdRan(err), ExitStatus(err), err
+}
+
+func cmdRan(err error) bool {
+	if err == nil {
+		return true
+	}
+	ee, ok := err.(*exec.ExitError)
+	if ok {
+		return ee.Exited()
+	}
+	return false
+}
+
+type exitStatus interface {
+	ExitStatus() int
+}
+
+// ExitStatus returns the exit status of the error if it is an exec.ExitError
+// or if it implements ExitStatus() int.
+// 0 if it is nil or 1 if it is a different error.
+func ExitStatus(err error) int {
+	if err == nil {
+		return 0
+	}
+	if e, ok := err.(exitStatus); ok {
+		return e.ExitStatus()
+	}
+	if e, ok := err.(*exec.ExitError); ok {
+		if ex, ok := e.Sys().(exitStatus); ok {
+			return ex.ExitStatus()
+		}
+	}
+	return 1
+}
diff --git a/sh/helpers.go b/sh/helpers.go
new file mode 100644
index 0000000..86b075e
--- /dev/null
+++ b/sh/helpers.go
@@ -0,0 +1,16 @@
+package sh
+
+import (
+	"fmt"
+	"os"
+)
+
+// Rm removes the given file or directory even if non-empty. It will not return
+// an error if the target doesn't exist, only if the target cannot be removed.
+func Rm(path string) error {
+	err := os.RemoveAll(path)
+	if err == nil || os.IsNotExist(err) {
+		return nil
+	}
+	return fmt.Errorf(`failed to remove %s: %v`, path, err)
+}
diff --git a/vendor/github.com/google/go-cmp/.travis.yml b/vendor/github.com/google/go-cmp/.travis.yml
deleted file mode 100644
index 9d9b7f9..0000000
--- a/vendor/github.com/google/go-cmp/.travis.yml
+++ /dev/null
@@ -1,18 +0,0 @@
-sudo: false
-language: go
-go:
-  - 1.x
-  - master
-matrix:
-  include:
-    - go: 1.6.x
-      script: go test -v -race ./...
-  allow_failures:
-    - go: master
-  fast_finish: true
-install:
-  - # Do nothing. This is needed to prevent default install action "go get -t -v ./..." from happening here (it is intended for this package to have no dependencies other than the standard library).
-script:
-  - diff -u <(echo -n) <(gofmt -d -s .)
-  - go tool vet .
-  - go test -v -race ./...
diff --git a/vendor/github.com/google/go-cmp/CONTRIBUTING.md b/vendor/github.com/google/go-cmp/CONTRIBUTING.md
deleted file mode 100644
index ae319c7..0000000
--- a/vendor/github.com/google/go-cmp/CONTRIBUTING.md
+++ /dev/null
@@ -1,23 +0,0 @@
-# How to Contribute
-
-We'd love to accept your patches and contributions to this project. There are
-just a few small guidelines you need to follow.
-
-## Contributor License Agreement
-
-Contributions to this project must be accompanied by a Contributor License
-Agreement. You (or your employer) retain the copyright to your contribution,
-this simply gives us permission to use and redistribute your contributions as
-part of the project. Head over to <https://cla.developers.google.com/> to see
-your current agreements on file or to sign a new one.
-
-You generally only need to submit a CLA once, so if you've already submitted one
-(even if it was for a different project), you probably don't need to do it
-again.
-
-## Code reviews
-
-All submissions, including submissions by project members, require review. We
-use GitHub pull requests for this purpose. Consult
-[GitHub Help](https://help.github.com/articles/about-pull-requests/) for more
-information on using pull requests.
diff --git a/vendor/github.com/google/go-cmp/LICENSE b/vendor/github.com/google/go-cmp/LICENSE
deleted file mode 100644
index 32017f8..0000000
--- a/vendor/github.com/google/go-cmp/LICENSE
+++ /dev/null
@@ -1,27 +0,0 @@
-Copyright (c) 2017 The Go Authors. 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.
-   * Neither the name of Google Inc. nor the names of its
-contributors may be used to endorse or promote products derived from
-this software without specific prior written permission.
-
-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
-OWNER 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/google/go-cmp/README.md b/vendor/github.com/google/go-cmp/README.md
deleted file mode 100644
index d82f10b..0000000
--- a/vendor/github.com/google/go-cmp/README.md
+++ /dev/null
@@ -1,44 +0,0 @@
-# Package for equality of Go values
-
-[![GoDoc](https://godoc.org/github.com/google/go-cmp/cmp?status.svg)][godoc]
-[![Build Status](https://travis-ci.org/google/go-cmp.svg?branch=master)][travis]
-
-This package is intended to be a more powerful and safer alternative to
-`reflect.DeepEqual` for comparing whether two values are semantically equal.
-
-The primary features of `cmp` are:
-
-* When the default behavior of equality does not suit the needs of the test,
-  custom equality functions can override the equality operation.
-  For example, an equality function may report floats as equal so long as they
-  are within some tolerance of each other.
-
-* Types that have an `Equal` method may use that method to determine equality.
-  This allows package authors to determine the equality operation for the types
-  that they define.
-
-* If no custom equality functions are used and no `Equal` method is defined,
-  equality is determined by recursively comparing the primitive kinds on both
-  values, much like `reflect.DeepEqual`. Unlike `reflect.DeepEqual`, unexported
-  fields are not compared by default; they result in panics unless suppressed
-  by using an `Ignore` option (see `cmpopts.IgnoreUnexported`) or explictly
-  compared using the `AllowUnexported` option.
-
-See the [GoDoc documentation][godoc] for more information.
-
-This is not an official Google product.
-
-[godoc]: https://godoc.org/github.com/google/go-cmp/cmp
-[travis]: https://travis-ci.org/google/go-cmp
-
-## Install
-
-```
-go get -u github.com/google/go-cmp/cmp
-```
-
-## License
-
-BSD - See [LICENSE][license] file
-
-[license]: https://github.com/google/go-cmp/blob/master/LICENSE
diff --git a/vendor/github.com/google/go-cmp/cmp/compare.go b/vendor/github.com/google/go-cmp/cmp/compare.go
deleted file mode 100644
index 5527f01..0000000
--- a/vendor/github.com/google/go-cmp/cmp/compare.go
+++ /dev/null
@@ -1,529 +0,0 @@
-// Copyright 2017, The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE.md file.
-
-// Package cmp determines equality of values.
-//
-// This package is intended to be a more powerful and safer alternative to
-// reflect.DeepEqual for comparing whether two values are semantically equal.
-//
-// The primary features of cmp are:
-//
-// • When the default behavior of equality does not suit the needs of the test,
-// custom equality functions can override the equality operation.
-// For example, an equality function may report floats as equal so long as they
-// are within some tolerance of each other.
-//
-// • Types that have an Equal method may use that method to determine equality.
-// This allows package authors to determine the equality operation for the types
-// that they define.
-//
-// • If no custom equality functions are used and no Equal method is defined,
-// equality is determined by recursively comparing the primitive kinds on both
-// values, much like reflect.DeepEqual. Unlike reflect.DeepEqual, unexported
-// fields are not compared by default; they result in panics unless suppressed
-// by using an Ignore option (see cmpopts.IgnoreUnexported) or explictly compared
-// using the AllowUnexported option.
-package cmp
-
-import (
-	"fmt"
-	"reflect"
-
-	"github.com/google/go-cmp/cmp/internal/diff"
-	"github.com/google/go-cmp/cmp/internal/function"
-	"github.com/google/go-cmp/cmp/internal/value"
-)
-
-// BUG: Maps with keys containing NaN values cannot be properly compared due to
-// the reflection package's inability to retrieve such entries. Equal will panic
-// anytime it comes across a NaN key, but this behavior may change.
-//
-// See https://golang.org/issue/11104 for more details.
-
-var nothing = reflect.Value{}
-
-// Equal reports whether x and y are equal by recursively applying the
-// following rules in the given order to x and y and all of their sub-values:
-//
-// • If two values are not of the same type, then they are never equal
-// and the overall result is false.
-//
-// • Let S be the set of all Ignore, Transformer, and Comparer options that
-// remain after applying all path filters, value filters, and type filters.
-// If at least one Ignore exists in S, then the comparison is ignored.
-// If the number of Transformer and Comparer options in S is greater than one,
-// then Equal panics because it is ambiguous which option to use.
-// If S contains a single Transformer, then use that to transform the current
-// values and recursively call Equal on the output values.
-// If S contains a single Comparer, then use that to compare the current values.
-// Otherwise, evaluation proceeds to the next rule.
-//
-// • If the values have an Equal method of the form "(T) Equal(T) bool" or
-// "(T) Equal(I) bool" where T is assignable to I, then use the result of
-// x.Equal(y). Otherwise, no such method exists and evaluation proceeds to
-// the next rule.
-//
-// • Lastly, try to compare x and y based on their basic kinds.
-// Simple kinds like booleans, integers, floats, complex numbers, strings, and
-// channels are compared using the equivalent of the == operator in Go.
-// Functions are only equal if they are both nil, otherwise they are unequal.
-// Pointers are equal if the underlying values they point to are also equal.
-// Interfaces are equal if their underlying concrete values are also equal.
-//
-// Structs are equal if all of their fields are equal. If a struct contains
-// unexported fields, Equal panics unless the AllowUnexported option is used or
-// an Ignore option (e.g., cmpopts.IgnoreUnexported) ignores that field.
-//
-// Arrays, slices, and maps are equal if they are both nil or both non-nil
-// with the same length and the elements at each index or key are equal.
-// Note that a non-nil empty slice and a nil slice are not equal.
-// To equate empty slices and maps, consider using cmpopts.EquateEmpty.
-// Map keys are equal according to the == operator.
-// To use custom comparisons for map keys, consider using cmpopts.SortMaps.
-func Equal(x, y interface{}, opts ...Option) bool {
-	s := newState(opts)
-	s.compareAny(reflect.ValueOf(x), reflect.ValueOf(y))
-	return s.result.Equal()
-}
-
-// Diff returns a human-readable report of the differences between two values.
-// It returns an empty string if and only if Equal returns true for the same
-// input values and options. The output string will use the "-" symbol to
-// indicate elements removed from x, and the "+" symbol to indicate elements
-// added to y.
-//
-// Do not depend on this output being stable.
-func Diff(x, y interface{}, opts ...Option) string {
-	r := new(defaultReporter)
-	opts = Options{Options(opts), r}
-	eq := Equal(x, y, opts...)
-	d := r.String()
-	if (d == "") != eq {
-		panic("inconsistent difference and equality results")
-	}
-	return d
-}
-
-type state struct {
-	// These fields represent the "comparison state".
-	// Calling statelessCompare must not result in observable changes to these.
-	result   diff.Result // The current result of comparison
-	curPath  Path        // The current path in the value tree
-	reporter reporter    // Optional reporter used for difference formatting
-
-	// dynChecker triggers pseudo-random checks for option correctness.
-	// It is safe for statelessCompare to mutate this value.
-	dynChecker dynChecker
-
-	// These fields, once set by processOption, will not change.
-	exporters map[reflect.Type]bool // Set of structs with unexported field visibility
-	opts      Options               // List of all fundamental and filter options
-}
-
-func newState(opts []Option) *state {
-	s := new(state)
-	for _, opt := range opts {
-		s.processOption(opt)
-	}
-	return s
-}
-
-func (s *state) processOption(opt Option) {
-	switch opt := opt.(type) {
-	case nil:
-	case Options:
-		for _, o := range opt {
-			s.processOption(o)
-		}
-	case coreOption:
-		type filtered interface {
-			isFiltered() bool
-		}
-		if fopt, ok := opt.(filtered); ok && !fopt.isFiltered() {
-			panic(fmt.Sprintf("cannot use an unfiltered option: %v", opt))
-		}
-		s.opts = append(s.opts, opt)
-	case visibleStructs:
-		if s.exporters == nil {
-			s.exporters = make(map[reflect.Type]bool)
-		}
-		for t := range opt {
-			s.exporters[t] = true
-		}
-	case reporter:
-		if s.reporter != nil {
-			panic("difference reporter already registered")
-		}
-		s.reporter = opt
-	default:
-		panic(fmt.Sprintf("unknown option %T", opt))
-	}
-}
-
-// statelessCompare compares two values and returns the result.
-// This function is stateless in that it does not alter the current result,
-// or output to any registered reporters.
-func (s *state) statelessCompare(vx, vy reflect.Value) diff.Result {
-	// We do not save and restore the curPath because all of the compareX
-	// methods should properly push and pop from the path.
-	// It is an implementation bug if the contents of curPath differs from
-	// when calling this function to when returning from it.
-
-	oldResult, oldReporter := s.result, s.reporter
-	s.result = diff.Result{} // Reset result
-	s.reporter = nil         // Remove reporter to avoid spurious printouts
-	s.compareAny(vx, vy)
-	res := s.result
-	s.result, s.reporter = oldResult, oldReporter
-	return res
-}
-
-func (s *state) compareAny(vx, vy reflect.Value) {
-	// TODO: Support cyclic data structures.
-
-	// Rule 0: Differing types are never equal.
-	if !vx.IsValid() || !vy.IsValid() {
-		s.report(vx.IsValid() == vy.IsValid(), vx, vy)
-		return
-	}
-	if vx.Type() != vy.Type() {
-		s.report(false, vx, vy) // Possible for path to be empty
-		return
-	}
-	t := vx.Type()
-	if len(s.curPath) == 0 {
-		s.curPath.push(&pathStep{typ: t})
-		defer s.curPath.pop()
-	}
-	vx, vy = s.tryExporting(vx, vy)
-
-	// Rule 1: Check whether an option applies on this node in the value tree.
-	if s.tryOptions(vx, vy, t) {
-		return
-	}
-
-	// Rule 2: Check whether the type has a valid Equal method.
-	if s.tryMethod(vx, vy, t) {
-		return
-	}
-
-	// Rule 3: Recursively descend into each value's underlying kind.
-	switch t.Kind() {
-	case reflect.Bool:
-		s.report(vx.Bool() == vy.Bool(), vx, vy)
-		return
-	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-		s.report(vx.Int() == vy.Int(), vx, vy)
-		return
-	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
-		s.report(vx.Uint() == vy.Uint(), vx, vy)
-		return
-	case reflect.Float32, reflect.Float64:
-		s.report(vx.Float() == vy.Float(), vx, vy)
-		return
-	case reflect.Complex64, reflect.Complex128:
-		s.report(vx.Complex() == vy.Complex(), vx, vy)
-		return
-	case reflect.String:
-		s.report(vx.String() == vy.String(), vx, vy)
-		return
-	case reflect.Chan, reflect.UnsafePointer:
-		s.report(vx.Pointer() == vy.Pointer(), vx, vy)
-		return
-	case reflect.Func:
-		s.report(vx.IsNil() && vy.IsNil(), vx, vy)
-		return
-	case reflect.Ptr:
-		if vx.IsNil() || vy.IsNil() {
-			s.report(vx.IsNil() && vy.IsNil(), vx, vy)
-			return
-		}
-		s.curPath.push(&indirect{pathStep{t.Elem()}})
-		defer s.curPath.pop()
-		s.compareAny(vx.Elem(), vy.Elem())
-		return
-	case reflect.Interface:
-		if vx.IsNil() || vy.IsNil() {
-			s.report(vx.IsNil() && vy.IsNil(), vx, vy)
-			return
-		}
-		if vx.Elem().Type() != vy.Elem().Type() {
-			s.report(false, vx.Elem(), vy.Elem())
-			return
-		}
-		s.curPath.push(&typeAssertion{pathStep{vx.Elem().Type()}})
-		defer s.curPath.pop()
-		s.compareAny(vx.Elem(), vy.Elem())
-		return
-	case reflect.Slice:
-		if vx.IsNil() || vy.IsNil() {
-			s.report(vx.IsNil() && vy.IsNil(), vx, vy)
-			return
-		}
-		fallthrough
-	case reflect.Array:
-		s.compareArray(vx, vy, t)
-		return
-	case reflect.Map:
-		s.compareMap(vx, vy, t)
-		return
-	case reflect.Struct:
-		s.compareStruct(vx, vy, t)
-		return
-	default:
-		panic(fmt.Sprintf("%v kind not handled", t.Kind()))
-	}
-}
-
-func (s *state) tryExporting(vx, vy reflect.Value) (reflect.Value, reflect.Value) {
-	if sf, ok := s.curPath[len(s.curPath)-1].(*structField); ok && sf.unexported {
-		if sf.force {
-			// Use unsafe pointer arithmetic to get read-write access to an
-			// unexported field in the struct.
-			vx = unsafeRetrieveField(sf.pvx, sf.field)
-			vy = unsafeRetrieveField(sf.pvy, sf.field)
-		} else {
-			// We are not allowed to export the value, so invalidate them
-			// so that tryOptions can panic later if not explicitly ignored.
-			vx = nothing
-			vy = nothing
-		}
-	}
-	return vx, vy
-}
-
-func (s *state) tryOptions(vx, vy reflect.Value, t reflect.Type) bool {
-	// If there were no FilterValues, we will not detect invalid inputs,
-	// so manually check for them and append invalid if necessary.
-	// We still evaluate the options since an ignore can override invalid.
-	opts := s.opts
-	if !vx.IsValid() || !vy.IsValid() {
-		opts = Options{opts, invalid{}}
-	}
-
-	// Evaluate all filters and apply the remaining options.
-	if opt := opts.filter(s, vx, vy, t); opt != nil {
-		return opt.apply(s, vx, vy)
-	}
-	return false
-}
-
-func (s *state) tryMethod(vx, vy reflect.Value, t reflect.Type) bool {
-	// Check if this type even has an Equal method.
-	m, ok := t.MethodByName("Equal")
-	if !ok || !function.IsType(m.Type, function.EqualAssignable) {
-		return false
-	}
-
-	eq := s.callTTBFunc(m.Func, vx, vy)
-	s.report(eq, vx, vy)
-	return true
-}
-
-func (s *state) callTRFunc(f, v reflect.Value) reflect.Value {
-	if !s.dynChecker.Next() {
-		return f.Call([]reflect.Value{v})[0]
-	}
-
-	// Run the function twice and ensure that we get the same results back.
-	// We run in goroutines so that the race detector (if enabled) can detect
-	// unsafe mutations to the input.
-	c := make(chan reflect.Value)
-	go detectRaces(c, f, v)
-	want := f.Call([]reflect.Value{v})[0]
-	if got := <-c; !s.statelessCompare(got, want).Equal() {
-		// To avoid false-positives with non-reflexive equality operations,
-		// we sanity check whether a value is equal to itself.
-		if !s.statelessCompare(want, want).Equal() {
-			return want
-		}
-		fn := getFuncName(f.Pointer())
-		panic(fmt.Sprintf("non-deterministic function detected: %s", fn))
-	}
-	return want
-}
-
-func (s *state) callTTBFunc(f, x, y reflect.Value) bool {
-	if !s.dynChecker.Next() {
-		return f.Call([]reflect.Value{x, y})[0].Bool()
-	}
-
-	// Swapping the input arguments is sufficient to check that
-	// f is symmetric and deterministic.
-	// We run in goroutines so that the race detector (if enabled) can detect
-	// unsafe mutations to the input.
-	c := make(chan reflect.Value)
-	go detectRaces(c, f, y, x)
-	want := f.Call([]reflect.Value{x, y})[0].Bool()
-	if got := <-c; !got.IsValid() || got.Bool() != want {
-		fn := getFuncName(f.Pointer())
-		panic(fmt.Sprintf("non-deterministic or non-symmetric function detected: %s", fn))
-	}
-	return want
-}
-
-func detectRaces(c chan<- reflect.Value, f reflect.Value, vs ...reflect.Value) {
-	var ret reflect.Value
-	defer func() {
-		recover() // Ignore panics, let the other call to f panic instead
-		c <- ret
-	}()
-	ret = f.Call(vs)[0]
-}
-
-func (s *state) compareArray(vx, vy reflect.Value, t reflect.Type) {
-	step := &sliceIndex{pathStep{t.Elem()}, 0, 0}
-	s.curPath.push(step)
-
-	// Compute an edit-script for slices vx and vy.
-	eq, es := diff.Difference(vx.Len(), vy.Len(), func(ix, iy int) diff.Result {
-		step.xkey, step.ykey = ix, iy
-		return s.statelessCompare(vx.Index(ix), vy.Index(iy))
-	})
-
-	// Equal or no edit-script, so report entire slices as is.
-	if eq || es == nil {
-		s.curPath.pop() // Pop first since we are reporting the whole slice
-		s.report(eq, vx, vy)
-		return
-	}
-
-	// Replay the edit-script.
-	var ix, iy int
-	for _, e := range es {
-		switch e {
-		case diff.UniqueX:
-			step.xkey, step.ykey = ix, -1
-			s.report(false, vx.Index(ix), nothing)
-			ix++
-		case diff.UniqueY:
-			step.xkey, step.ykey = -1, iy
-			s.report(false, nothing, vy.Index(iy))
-			iy++
-		default:
-			step.xkey, step.ykey = ix, iy
-			if e == diff.Identity {
-				s.report(true, vx.Index(ix), vy.Index(iy))
-			} else {
-				s.compareAny(vx.Index(ix), vy.Index(iy))
-			}
-			ix++
-			iy++
-		}
-	}
-	s.curPath.pop()
-	return
-}
-
-func (s *state) compareMap(vx, vy reflect.Value, t reflect.Type) {
-	if vx.IsNil() || vy.IsNil() {
-		s.report(vx.IsNil() && vy.IsNil(), vx, vy)
-		return
-	}
-
-	// We combine and sort the two map keys so that we can perform the
-	// comparisons in a deterministic order.
-	step := &mapIndex{pathStep: pathStep{t.Elem()}}
-	s.curPath.push(step)
-	defer s.curPath.pop()
-	for _, k := range value.SortKeys(append(vx.MapKeys(), vy.MapKeys()...)) {
-		step.key = k
-		vvx := vx.MapIndex(k)
-		vvy := vy.MapIndex(k)
-		switch {
-		case vvx.IsValid() && vvy.IsValid():
-			s.compareAny(vvx, vvy)
-		case vvx.IsValid() && !vvy.IsValid():
-			s.report(false, vvx, nothing)
-		case !vvx.IsValid() && vvy.IsValid():
-			s.report(false, nothing, vvy)
-		default:
-			// It is possible for both vvx and vvy to be invalid if the
-			// key contained a NaN value in it. There is no way in
-			// reflection to be able to retrieve these values.
-			// See https://golang.org/issue/11104
-			panic(fmt.Sprintf("%#v has map key with NaNs", s.curPath))
-		}
-	}
-}
-
-func (s *state) compareStruct(vx, vy reflect.Value, t reflect.Type) {
-	var vax, vay reflect.Value // Addressable versions of vx and vy
-
-	step := &structField{}
-	s.curPath.push(step)
-	defer s.curPath.pop()
-	for i := 0; i < t.NumField(); i++ {
-		vvx := vx.Field(i)
-		vvy := vy.Field(i)
-		step.typ = t.Field(i).Type
-		step.name = t.Field(i).Name
-		step.idx = i
-		step.unexported = !isExported(step.name)
-		if step.unexported {
-			// Defer checking of unexported fields until later to give an
-			// Ignore a chance to ignore the field.
-			if !vax.IsValid() || !vay.IsValid() {
-				// For unsafeRetrieveField to work, the parent struct must
-				// be addressable. Create a new copy of the values if
-				// necessary to make them addressable.
-				vax = makeAddressable(vx)
-				vay = makeAddressable(vy)
-			}
-			step.force = s.exporters[t]
-			step.pvx = vax
-			step.pvy = vay
-			step.field = t.Field(i)
-		}
-		s.compareAny(vvx, vvy)
-	}
-}
-
-// report records the result of a single comparison.
-// It also calls Report if any reporter is registered.
-func (s *state) report(eq bool, vx, vy reflect.Value) {
-	if eq {
-		s.result.NSame++
-	} else {
-		s.result.NDiff++
-	}
-	if s.reporter != nil {
-		s.reporter.Report(vx, vy, eq, s.curPath)
-	}
-}
-
-// dynChecker tracks the state needed to periodically perform checks that
-// user provided functions are symmetric and deterministic.
-// The zero value is safe for immediate use.
-type dynChecker struct{ curr, next int }
-
-// Next increments the state and reports whether a check should be performed.
-//
-// Checks occur every Nth function call, where N is a triangular number:
-//	0 1 3 6 10 15 21 28 36 45 55 66 78 91 105 120 136 153 171 190 ...
-// See https://en.wikipedia.org/wiki/Triangular_number
-//
-// This sequence ensures that the cost of checks drops significantly as
-// the number of functions calls grows larger.
-func (dc *dynChecker) Next() bool {
-	ok := dc.curr == dc.next
-	if ok {
-		dc.curr = 0
-		dc.next++
-	}
-	dc.curr++
-	return ok
-}
-
-// makeAddressable returns a value that is always addressable.
-// It returns the input verbatim if it is already addressable,
-// otherwise it creates a new value and returns an addressable copy.
-func makeAddressable(v reflect.Value) reflect.Value {
-	if v.CanAddr() {
-		return v
-	}
-	vc := reflect.New(v.Type()).Elem()
-	vc.Set(v)
-	return vc
-}
diff --git a/vendor/github.com/google/go-cmp/cmp/internal/diff/debug_disable.go b/vendor/github.com/google/go-cmp/cmp/internal/diff/debug_disable.go
deleted file mode 100644
index 42afa49..0000000
--- a/vendor/github.com/google/go-cmp/cmp/internal/diff/debug_disable.go
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright 2017, The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE.md file.
-
-// +build !debug
-
-package diff
-
-var debug debugger
-
-type debugger struct{}
-
-func (debugger) Begin(_, _ int, f EqualFunc, _, _ *EditScript) EqualFunc {
-	return f
-}
-func (debugger) Update() {}
-func (debugger) Finish() {}
diff --git a/vendor/github.com/google/go-cmp/cmp/internal/diff/debug_enable.go b/vendor/github.com/google/go-cmp/cmp/internal/diff/debug_enable.go
deleted file mode 100644
index ba46c62..0000000
--- a/vendor/github.com/google/go-cmp/cmp/internal/diff/debug_enable.go
+++ /dev/null
@@ -1,122 +0,0 @@
-// Copyright 2017, The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE.md file.
-
-// +build debug
-
-package diff
-
-import (
-	"fmt"
-	"strings"
-	"sync"
-	"time"
-)
-
-// The algorithm can be seen running in real-time by enabling debugging:
-//	go test -tags=debug -v
-//
-// Example output:
-//	=== RUN   TestDifference/#34
-//	┌───────────────────────────────┐
-//	│ \ · · · · · · · · · · · · · · │
-//	│ · # · · · · · · · · · · · · · │
-//	│ · \ · · · · · · · · · · · · · │
-//	│ · · \ · · · · · · · · · · · · │
-//	│ · · · X # · · · · · · · · · · │
-//	│ · · · # \ · · · · · · · · · · │
-//	│ · · · · · # # · · · · · · · · │
-//	│ · · · · · # \ · · · · · · · · │
-//	│ · · · · · · · \ · · · · · · · │
-//	│ · · · · · · · · \ · · · · · · │
-//	│ · · · · · · · · · \ · · · · · │
-//	│ · · · · · · · · · · \ · · # · │
-//	│ · · · · · · · · · · · \ # # · │
-//	│ · · · · · · · · · · · # # # · │
-//	│ · · · · · · · · · · # # # # · │
-//	│ · · · · · · · · · # # # # # · │
-//	│ · · · · · · · · · · · · · · \ │
-//	└───────────────────────────────┘
-//	[.Y..M.XY......YXYXY.|]
-//
-// The grid represents the edit-graph where the horizontal axis represents
-// list X and the vertical axis represents list Y. The start of the two lists
-// is the top-left, while the ends are the bottom-right. The '·' represents
-// an unexplored node in the graph. The '\' indicates that the two symbols
-// from list X and Y are equal. The 'X' indicates that two symbols are similar
-// (but not exactly equal) to each other. The '#' indicates that the two symbols
-// are different (and not similar). The algorithm traverses this graph trying to
-// make the paths starting in the top-left and the bottom-right connect.
-//
-// The series of '.', 'X', 'Y', and 'M' characters at the bottom represents
-// the currently established path from the forward and reverse searches,
-// seperated by a '|' character.
-
-const (
-	updateDelay  = 100 * time.Millisecond
-	finishDelay  = 500 * time.Millisecond
-	ansiTerminal = true // ANSI escape codes used to move terminal cursor
-)
-
-var debug debugger
-
-type debugger struct {
-	sync.Mutex
-	p1, p2           EditScript
-	fwdPath, revPath *EditScript
-	grid             []byte
-	lines            int
-}
-
-func (dbg *debugger) Begin(nx, ny int, f EqualFunc, p1, p2 *EditScript) EqualFunc {
-	dbg.Lock()
-	dbg.fwdPath, dbg.revPath = p1, p2
-	top := "┌─" + strings.Repeat("──", nx) + "┐\n"
-	row := "│ " + strings.Repeat("· ", nx) + "│\n"
-	btm := "└─" + strings.Repeat("──", nx) + "┘\n"
-	dbg.grid = []byte(top + strings.Repeat(row, ny) + btm)
-	dbg.lines = strings.Count(dbg.String(), "\n")
-	fmt.Print(dbg)
-
-	// Wrap the EqualFunc so that we can intercept each result.
-	return func(ix, iy int) (r Result) {
-		cell := dbg.grid[len(top)+iy*len(row):][len("│ ")+len("· ")*ix:][:len("·")]
-		for i := range cell {
-			cell[i] = 0 // Zero out the multiple bytes of UTF-8 middle-dot
-		}
-		switch r = f(ix, iy); {
-		case r.Equal():
-			cell[0] = '\\'
-		case r.Similar():
-			cell[0] = 'X'
-		default:
-			cell[0] = '#'
-		}
-		return
-	}
-}
-
-func (dbg *debugger) Update() {
-	dbg.print(updateDelay)
-}
-
-func (dbg *debugger) Finish() {
-	dbg.print(finishDelay)
-	dbg.Unlock()
-}
-
-func (dbg *debugger) String() string {
-	dbg.p1, dbg.p2 = *dbg.fwdPath, dbg.p2[:0]
-	for i := len(*dbg.revPath) - 1; i >= 0; i-- {
-		dbg.p2 = append(dbg.p2, (*dbg.revPath)[i])
-	}
-	return fmt.Sprintf("%s[%v|%v]\n\n", dbg.grid, dbg.p1, dbg.p2)
-}
-
-func (dbg *debugger) print(d time.Duration) {
-	if ansiTerminal {
-		fmt.Printf("\x1b[%dA", dbg.lines) // Reset terminal cursor
-	}
-	fmt.Print(dbg)
-	time.Sleep(d)
-}
diff --git a/vendor/github.com/google/go-cmp/cmp/internal/diff/diff.go b/vendor/github.com/google/go-cmp/cmp/internal/diff/diff.go
deleted file mode 100644
index baa41fd..0000000
--- a/vendor/github.com/google/go-cmp/cmp/internal/diff/diff.go
+++ /dev/null
@@ -1,373 +0,0 @@
-// Copyright 2017, The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE.md file.
-
-// Package diff implements an algorithm for producing edit-scripts.
-// The edit-script is a sequence of operations needed to transform one list
-// of symbols into another (or vice-versa). The edits allowed are insertions,
-// deletions, and modifications. The summation of all edits is called the
-// Levenshtein distance as this problem is well-known in computer science.
-//
-// This package prioritizes performance over accuracy. That is, the run time
-// is more important than obtaining a minimal Levenshtein distance.
-package diff
-
-// EditType represents a single operation within an edit-script.
-type EditType uint8
-
-const (
-	// Identity indicates that a symbol pair is identical in both list X and Y.
-	Identity EditType = iota
-	// UniqueX indicates that a symbol only exists in X and not Y.
-	UniqueX
-	// UniqueY indicates that a symbol only exists in Y and not X.
-	UniqueY
-	// Modified indicates that a symbol pair is a modification of each other.
-	Modified
-)
-
-// EditScript represents the series of differences between two lists.
-type EditScript []EditType
-
-// String returns a human-readable string representing the edit-script where
-// Identity, UniqueX, UniqueY, and Modified are represented by the
-// '.', 'X', 'Y', and 'M' characters, respectively.
-func (es EditScript) String() string {
-	b := make([]byte, len(es))
-	for i, e := range es {
-		switch e {
-		case Identity:
-			b[i] = '.'
-		case UniqueX:
-			b[i] = 'X'
-		case UniqueY:
-			b[i] = 'Y'
-		case Modified:
-			b[i] = 'M'
-		default:
-			panic("invalid edit-type")
-		}
-	}
-	return string(b)
-}
-
-// stats returns a histogram of the number of each type of edit operation.
-func (es EditScript) stats() (s struct{ NI, NX, NY, NM int }) {
-	for _, e := range es {
-		switch e {
-		case Identity:
-			s.NI++
-		case UniqueX:
-			s.NX++
-		case UniqueY:
-			s.NY++
-		case Modified:
-			s.NM++
-		default:
-			panic("invalid edit-type")
-		}
-	}
-	return
-}
-
-// Dist is the Levenshtein distance and is guaranteed to be 0 if and only if
-// lists X and Y are equal.
-func (es EditScript) Dist() int { return len(es) - es.stats().NI }
-
-// LenX is the length of the X list.
-func (es EditScript) LenX() int { return len(es) - es.stats().NY }
-
-// LenY is the length of the Y list.
-func (es EditScript) LenY() int { return len(es) - es.stats().NX }
-
-// EqualFunc reports whether the symbols at indexes ix and iy are equal.
-// When called by Difference, the index is guaranteed to be within nx and ny.
-type EqualFunc func(ix int, iy int) Result
-
-// Result is the result of comparison.
-// NSame is the number of sub-elements that are equal.
-// NDiff is the number of sub-elements that are not equal.
-type Result struct{ NSame, NDiff int }
-
-// Equal indicates whether the symbols are equal. Two symbols are equal
-// if and only if NDiff == 0. If Equal, then they are also Similar.
-func (r Result) Equal() bool { return r.NDiff == 0 }
-
-// Similar indicates whether two symbols are similar and may be represented
-// by using the Modified type. As a special case, we consider binary comparisons
-// (i.e., those that return Result{1, 0} or Result{0, 1}) to be similar.
-//
-// The exact ratio of NSame to NDiff to determine similarity may change.
-func (r Result) Similar() bool {
-	// Use NSame+1 to offset NSame so that binary comparisons are similar.
-	return r.NSame+1 >= r.NDiff
-}
-
-// Difference reports whether two lists of lengths nx and ny are equal
-// given the definition of equality provided as f.
-//
-// This function may return a edit-script, which is a sequence of operations
-// needed to convert one list into the other. If non-nil, the following
-// invariants for the edit-script are maintained:
-//	• eq == (es.Dist()==0)
-//	• nx == es.LenX()
-//	• ny == es.LenY()
-//
-// This algorithm is not guaranteed to be an optimal solution (i.e., one that
-// produces an edit-script with a minimal Levenshtein distance). This algorithm
-// favors performance over optimality. The exact output is not guaranteed to
-// be stable and may change over time.
-func Difference(nx, ny int, f EqualFunc) (eq bool, es EditScript) {
-	es = searchGraph(nx, ny, f)
-	st := es.stats()
-	eq = len(es) == st.NI
-	if !eq && st.NI < (nx+ny)/4 {
-		return eq, nil // Edit-script more distracting than helpful
-	}
-	return eq, es
-}
-
-func searchGraph(nx, ny int, f EqualFunc) EditScript {
-	// This algorithm is based on traversing what is known as an "edit-graph".
-	// See Figure 1 from "An O(ND) Difference Algorithm and Its Variations"
-	// by Eugene W. Myers. Since D can be as large as N itself, this is
-	// effectively O(N^2). Unlike the algorithm from that paper, we are not
-	// interested in the optimal path, but at least some "decent" path.
-	//
-	// For example, let X and Y be lists of symbols:
-	//	X = [A B C A B B A]
-	//	Y = [C B A B A C]
-	//
-	// The edit-graph can be drawn as the following:
-	//	   A B C A B B A
-	//	  ┌─────────────┐
-	//	C │_|_|\|_|_|_|_│ 0
-	//	B │_|\|_|_|\|\|_│ 1
-	//	A │\|_|_|\|_|_|\│ 2
-	//	B │_|\|_|_|\|\|_│ 3
-	//	A │\|_|_|\|_|_|\│ 4
-	//	C │ | |\| | | | │ 5
-	//	  └─────────────┘ 6
-	//	   0 1 2 3 4 5 6 7
-	//
-	// List X is written along the horizontal axis, while list Y is written
-	// along the vertical axis. At any point on this grid, if the symbol in
-	// list X matches the corresponding symbol in list Y, then a '\' is drawn.
-	// The goal of any minimal edit-script algorithm is to find a path from the
-	// top-left corner to the bottom-right corner, while traveling through the
-	// fewest horizontal or vertical edges.
-	// A horizontal edge is equivalent to inserting a symbol from list X.
-	// A vertical edge is equivalent to inserting a symbol from list Y.
-	// A diagonal edge is equivalent to a matching symbol between both X and Y.
-
-	// Invariants:
-	//	• 0 ≤ fwdPath.X ≤ (fwdFrontier.X, revFrontier.X) ≤ revPath.X ≤ nx
-	//	• 0 ≤ fwdPath.Y ≤ (fwdFrontier.Y, revFrontier.Y) ≤ revPath.Y ≤ ny
-	//
-	// In general:
-	//	• fwdFrontier.X < revFrontier.X
-	//	• fwdFrontier.Y < revFrontier.Y
-	// Unless, it is time for the algorithm to terminate.
-	fwdPath := path{+1, point{0, 0}, make(EditScript, 0, (nx+ny)/2)}
-	revPath := path{-1, point{nx, ny}, make(EditScript, 0)}
-	fwdFrontier := fwdPath.point // Forward search frontier
-	revFrontier := revPath.point // Reverse search frontier
-
-	// Search budget bounds the cost of searching for better paths.
-	// The longest sequence of non-matching symbols that can be tolerated is
-	// approximately the square-root of the search budget.
-	searchBudget := 4 * (nx + ny) // O(n)
-
-	// The algorithm below is a greedy, meet-in-the-middle algorithm for
-	// computing sub-optimal edit-scripts between two lists.
-	//
-	// The algorithm is approximately as follows:
-	//	• Searching for differences switches back-and-forth between
-	//	a search that starts at the beginning (the top-left corner), and
-	//	a search that starts at the end (the bottom-right corner). The goal of
-	//	the search is connect with the search from the opposite corner.
-	//	• As we search, we build a path in a greedy manner, where the first
-	//	match seen is added to the path (this is sub-optimal, but provides a
-	//	decent result in practice). When matches are found, we try the next pair
-	//	of symbols in the lists and follow all matches as far as possible.
-	//	• When searching for matches, we search along a diagonal going through
-	//	through the "frontier" point. If no matches are found, we advance the
-	//	frontier towards the opposite corner.
-	//	• This algorithm terminates when either the X coordinates or the
-	//	Y coordinates of the forward and reverse frontier points ever intersect.
-	//
-	// This algorithm is correct even if searching only in the forward direction
-	// or in the reverse direction. We do both because it is commonly observed
-	// that two lists commonly differ because elements were added to the front
-	// or end of the other list.
-	//
-	// Running the tests with the "debug" build tag prints a visualization of
-	// the algorithm running in real-time. This is educational for understanding
-	// how the algorithm works. See debug_enable.go.
-	f = debug.Begin(nx, ny, f, &fwdPath.es, &revPath.es)
-	for {
-		// Forward search from the beginning.
-		if fwdFrontier.X >= revFrontier.X || fwdFrontier.Y >= revFrontier.Y || searchBudget == 0 {
-			break
-		}
-		for stop1, stop2, i := false, false, 0; !(stop1 && stop2) && searchBudget > 0; i++ {
-			// Search in a diagonal pattern for a match.
-			z := zigzag(i)
-			p := point{fwdFrontier.X + z, fwdFrontier.Y - z}
-			switch {
-			case p.X >= revPath.X || p.Y < fwdPath.Y:
-				stop1 = true // Hit top-right corner
-			case p.Y >= revPath.Y || p.X < fwdPath.X:
-				stop2 = true // Hit bottom-left corner
-			case f(p.X, p.Y).Equal():
-				// Match found, so connect the path to this point.
-				fwdPath.connect(p, f)
-				fwdPath.append(Identity)
-				// Follow sequence of matches as far as possible.
-				for fwdPath.X < revPath.X && fwdPath.Y < revPath.Y {
-					if !f(fwdPath.X, fwdPath.Y).Equal() {
-						break
-					}
-					fwdPath.append(Identity)
-				}
-				fwdFrontier = fwdPath.point
-				stop1, stop2 = true, true
-			default:
-				searchBudget-- // Match not found
-			}
-			debug.Update()
-		}
-		// Advance the frontier towards reverse point.
-		if revPath.X-fwdFrontier.X >= revPath.Y-fwdFrontier.Y {
-			fwdFrontier.X++
-		} else {
-			fwdFrontier.Y++
-		}
-
-		// Reverse search from the end.
-		if fwdFrontier.X >= revFrontier.X || fwdFrontier.Y >= revFrontier.Y || searchBudget == 0 {
-			break
-		}
-		for stop1, stop2, i := false, false, 0; !(stop1 && stop2) && searchBudget > 0; i++ {
-			// Search in a diagonal pattern for a match.
-			z := zigzag(i)
-			p := point{revFrontier.X - z, revFrontier.Y + z}
-			switch {
-			case fwdPath.X >= p.X || revPath.Y < p.Y:
-				stop1 = true // Hit bottom-left corner
-			case fwdPath.Y >= p.Y || revPath.X < p.X:
-				stop2 = true // Hit top-right corner
-			case f(p.X-1, p.Y-1).Equal():
-				// Match found, so connect the path to this point.
-				revPath.connect(p, f)
-				revPath.append(Identity)
-				// Follow sequence of matches as far as possible.
-				for fwdPath.X < revPath.X && fwdPath.Y < revPath.Y {
-					if !f(revPath.X-1, revPath.Y-1).Equal() {
-						break
-					}
-					revPath.append(Identity)
-				}
-				revFrontier = revPath.point
-				stop1, stop2 = true, true
-			default:
-				searchBudget-- // Match not found
-			}
-			debug.Update()
-		}
-		// Advance the frontier towards forward point.
-		if revFrontier.X-fwdPath.X >= revFrontier.Y-fwdPath.Y {
-			revFrontier.X--
-		} else {
-			revFrontier.Y--
-		}
-	}
-
-	// Join the forward and reverse paths and then append the reverse path.
-	fwdPath.connect(revPath.point, f)
-	for i := len(revPath.es) - 1; i >= 0; i-- {
-		t := revPath.es[i]
-		revPath.es = revPath.es[:i]
-		fwdPath.append(t)
-	}
-	debug.Finish()
-	return fwdPath.es
-}
-
-type path struct {
-	dir   int // +1 if forward, -1 if reverse
-	point     // Leading point of the EditScript path
-	es    EditScript
-}
-
-// connect appends any necessary Identity, Modified, UniqueX, or UniqueY types
-// to the edit-script to connect p.point to dst.
-func (p *path) connect(dst point, f EqualFunc) {
-	if p.dir > 0 {
-		// Connect in forward direction.
-		for dst.X > p.X && dst.Y > p.Y {
-			switch r := f(p.X, p.Y); {
-			case r.Equal():
-				p.append(Identity)
-			case r.Similar():
-				p.append(Modified)
-			case dst.X-p.X >= dst.Y-p.Y:
-				p.append(UniqueX)
-			default:
-				p.append(UniqueY)
-			}
-		}
-		for dst.X > p.X {
-			p.append(UniqueX)
-		}
-		for dst.Y > p.Y {
-			p.append(UniqueY)
-		}
-	} else {
-		// Connect in reverse direction.
-		for p.X > dst.X && p.Y > dst.Y {
-			switch r := f(p.X-1, p.Y-1); {
-			case r.Equal():
-				p.append(Identity)
-			case r.Similar():
-				p.append(Modified)
-			case p.Y-dst.Y >= p.X-dst.X:
-				p.append(UniqueY)
-			default:
-				p.append(UniqueX)
-			}
-		}
-		for p.X > dst.X {
-			p.append(UniqueX)
-		}
-		for p.Y > dst.Y {
-			p.append(UniqueY)
-		}
-	}
-}
-
-func (p *path) append(t EditType) {
-	p.es = append(p.es, t)
-	switch t {
-	case Identity, Modified:
-		p.add(p.dir, p.dir)
-	case UniqueX:
-		p.add(p.dir, 0)
-	case UniqueY:
-		p.add(0, p.dir)
-	}
-	debug.Update()
-}
-
-type point struct{ X, Y int }
-
-func (p *point) add(dx, dy int) { p.X += dx; p.Y += dy }
-
-// zigzag maps a consecutive sequence of integers to a zig-zag sequence.
-//	[0 1 2 3 4 5 ...] => [0 -1 +1 -2 +2 ...]
-func zigzag(x int) int {
-	if x&1 != 0 {
-		x = ^x
-	}
-	return x >> 1
-}
diff --git a/vendor/github.com/google/go-cmp/cmp/internal/function/func.go b/vendor/github.com/google/go-cmp/cmp/internal/function/func.go
deleted file mode 100644
index 4c35ff1..0000000
--- a/vendor/github.com/google/go-cmp/cmp/internal/function/func.go
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2017, The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE.md file.
-
-// Package function identifies function types.
-package function
-
-import "reflect"
-
-type funcType int
-
-const (
-	_ funcType = iota
-
-	ttbFunc // func(T, T) bool
-	tibFunc // func(T, I) bool
-	trFunc  // func(T) R
-
-	Equal           = ttbFunc // func(T, T) bool
-	EqualAssignable = tibFunc // func(T, I) bool; encapsulates func(T, T) bool
-	Transformer     = trFunc  // func(T) R
-	ValueFilter     = ttbFunc // func(T, T) bool
-	Less            = ttbFunc // func(T, T) bool
-)
-
-var boolType = reflect.TypeOf(true)
-
-// IsType reports whether the reflect.Type is of the specified function type.
-func IsType(t reflect.Type, ft funcType) bool {
-	if t == nil || t.Kind() != reflect.Func || t.IsVariadic() {
-		return false
-	}
-	ni, no := t.NumIn(), t.NumOut()
-	switch ft {
-	case ttbFunc: // func(T, T) bool
-		if ni == 2 && no == 1 && t.In(0) == t.In(1) && t.Out(0) == boolType {
-			return true
-		}
-	case tibFunc: // func(T, I) bool
-		if ni == 2 && no == 1 && t.In(0).AssignableTo(t.In(1)) && t.Out(0) == boolType {
-			return true
-		}
-	case trFunc: // func(T) R
-		if ni == 1 && no == 1 {
-			return true
-		}
-	}
-	return false
-}
diff --git a/vendor/github.com/google/go-cmp/cmp/internal/value/format.go b/vendor/github.com/google/go-cmp/cmp/internal/value/format.go
deleted file mode 100644
index abaeca8..0000000
--- a/vendor/github.com/google/go-cmp/cmp/internal/value/format.go
+++ /dev/null
@@ -1,259 +0,0 @@
-// Copyright 2017, The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE.md file.
-
-// Package value provides functionality for reflect.Value types.
-package value
-
-import (
-	"fmt"
-	"reflect"
-	"strings"
-	"unicode"
-	"unicode/utf8"
-)
-
-// formatFakePointers controls whether to substitute pointer addresses with nil.
-// This is used for deterministic testing.
-var formatFakePointers = false
-
-var stringerIface = reflect.TypeOf((*fmt.Stringer)(nil)).Elem()
-
-// Format formats the value v as a string.
-//
-// This is similar to fmt.Sprintf("%+v", v) except this:
-//	* Prints the type unless it can be elided
-//	* Avoids printing struct fields that are zero
-//	* Prints a nil-slice as being nil, not empty
-//	* Prints map entries in deterministic order
-func Format(v reflect.Value, useStringer bool) string {
-	return formatAny(v, formatConfig{useStringer, true, true, !formatFakePointers}, nil)
-}
-
-type formatConfig struct {
-	useStringer    bool // Should the String method be used if available?
-	printType      bool // Should we print the type before the value?
-	followPointers bool // Should we recursively follow pointers?
-	realPointers   bool // Should we print the real address of pointers?
-}
-
-func formatAny(v reflect.Value, conf formatConfig, visited map[uintptr]bool) string {
-	// TODO: Should this be a multi-line printout in certain situations?
-
-	if !v.IsValid() {
-		return "<non-existent>"
-	}
-	if conf.useStringer && v.Type().Implements(stringerIface) && v.CanInterface() {
-		if (v.Kind() == reflect.Ptr || v.Kind() == reflect.Interface) && v.IsNil() {
-			return "<nil>"
-		}
-		return fmt.Sprintf("%q", v.Interface().(fmt.Stringer).String())
-	}
-
-	switch v.Kind() {
-	case reflect.Bool:
-		return formatPrimitive(v.Type(), v.Bool(), conf)
-	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-		return formatPrimitive(v.Type(), v.Int(), conf)
-	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
-		if v.Type().PkgPath() == "" || v.Kind() == reflect.Uintptr {
-			// Unnamed uints are usually bytes or words, so use hexadecimal.
-			return formatPrimitive(v.Type(), formatHex(v.Uint()), conf)
-		}
-		return formatPrimitive(v.Type(), v.Uint(), conf)
-	case reflect.Float32, reflect.Float64:
-		return formatPrimitive(v.Type(), v.Float(), conf)
-	case reflect.Complex64, reflect.Complex128:
-		return formatPrimitive(v.Type(), v.Complex(), conf)
-	case reflect.String:
-		return formatPrimitive(v.Type(), fmt.Sprintf("%q", v), conf)
-	case reflect.UnsafePointer, reflect.Chan, reflect.Func:
-		return formatPointer(v, conf)
-	case reflect.Ptr:
-		if v.IsNil() {
-			if conf.printType {
-				return fmt.Sprintf("(%v)(nil)", v.Type())
-			}
-			return "<nil>"
-		}
-		if visited[v.Pointer()] || !conf.followPointers {
-			return formatPointer(v, conf)
-		}
-		visited = insertPointer(visited, v.Pointer())
-		return "&" + formatAny(v.Elem(), conf, visited)
-	case reflect.Interface:
-		if v.IsNil() {
-			if conf.printType {
-				return fmt.Sprintf("%v(nil)", v.Type())
-			}
-			return "<nil>"
-		}
-		return formatAny(v.Elem(), conf, visited)
-	case reflect.Slice:
-		if v.IsNil() {
-			if conf.printType {
-				return fmt.Sprintf("%v(nil)", v.Type())
-			}
-			return "<nil>"
-		}
-		if visited[v.Pointer()] {
-			return formatPointer(v, conf)
-		}
-		visited = insertPointer(visited, v.Pointer())
-		fallthrough
-	case reflect.Array:
-		var ss []string
-		subConf := conf
-		subConf.printType = v.Type().Elem().Kind() == reflect.Interface
-		for i := 0; i < v.Len(); i++ {
-			s := formatAny(v.Index(i), subConf, visited)
-			ss = append(ss, s)
-		}
-		s := fmt.Sprintf("{%s}", strings.Join(ss, ", "))
-		if conf.printType {
-			return v.Type().String() + s
-		}
-		return s
-	case reflect.Map:
-		if v.IsNil() {
-			if conf.printType {
-				return fmt.Sprintf("%v(nil)", v.Type())
-			}
-			return "<nil>"
-		}
-		if visited[v.Pointer()] {
-			return formatPointer(v, conf)
-		}
-		visited = insertPointer(visited, v.Pointer())
-
-		var ss []string
-		subConf := conf
-		subConf.printType = v.Type().Elem().Kind() == reflect.Interface
-		for _, k := range SortKeys(v.MapKeys()) {
-			sk := formatAny(k, formatConfig{realPointers: conf.realPointers}, visited)
-			sv := formatAny(v.MapIndex(k), subConf, visited)
-			ss = append(ss, fmt.Sprintf("%s: %s", sk, sv))
-		}
-		s := fmt.Sprintf("{%s}", strings.Join(ss, ", "))
-		if conf.printType {
-			return v.Type().String() + s
-		}
-		return s
-	case reflect.Struct:
-		var ss []string
-		subConf := conf
-		subConf.printType = true
-		for i := 0; i < v.NumField(); i++ {
-			vv := v.Field(i)
-			if isZero(vv) {
-				continue // Elide zero value fields
-			}
-			name := v.Type().Field(i).Name
-			subConf.useStringer = conf.useStringer && isExported(name)
-			s := formatAny(vv, subConf, visited)
-			ss = append(ss, fmt.Sprintf("%s: %s", name, s))
-		}
-		s := fmt.Sprintf("{%s}", strings.Join(ss, ", "))
-		if conf.printType {
-			return v.Type().String() + s
-		}
-		return s
-	default:
-		panic(fmt.Sprintf("%v kind not handled", v.Kind()))
-	}
-}
-
-func formatPrimitive(t reflect.Type, v interface{}, conf formatConfig) string {
-	if conf.printType && t.PkgPath() != "" {
-		return fmt.Sprintf("%v(%v)", t, v)
-	}
-	return fmt.Sprintf("%v", v)
-}
-
-func formatPointer(v reflect.Value, conf formatConfig) string {
-	p := v.Pointer()
-	if !conf.realPointers {
-		p = 0 // For deterministic printing purposes
-	}
-	s := formatHex(uint64(p))
-	if conf.printType {
-		return fmt.Sprintf("(%v)(%s)", v.Type(), s)
-	}
-	return s
-}
-
-func formatHex(u uint64) string {
-	var f string
-	switch {
-	case u <= 0xff:
-		f = "0x%02x"
-	case u <= 0xffff:
-		f = "0x%04x"
-	case u <= 0xffffff:
-		f = "0x%06x"
-	case u <= 0xffffffff:
-		f = "0x%08x"
-	case u <= 0xffffffffff:
-		f = "0x%010x"
-	case u <= 0xffffffffffff:
-		f = "0x%012x"
-	case u <= 0xffffffffffffff:
-		f = "0x%014x"
-	case u <= 0xffffffffffffffff:
-		f = "0x%016x"
-	}
-	return fmt.Sprintf(f, u)
-}
-
-// insertPointer insert p into m, allocating m if necessary.
-func insertPointer(m map[uintptr]bool, p uintptr) map[uintptr]bool {
-	if m == nil {
-		m = make(map[uintptr]bool)
-	}
-	m[p] = true
-	return m
-}
-
-// isZero reports whether v is the zero value.
-// This does not rely on Interface and so can be used on unexported fields.
-func isZero(v reflect.Value) bool {
-	switch v.Kind() {
-	case reflect.Bool:
-		return v.Bool() == false
-	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-		return v.Int() == 0
-	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
-		return v.Uint() == 0
-	case reflect.Float32, reflect.Float64:
-		return v.Float() == 0
-	case reflect.Complex64, reflect.Complex128:
-		return v.Complex() == 0
-	case reflect.String:
-		return v.String() == ""
-	case reflect.UnsafePointer:
-		return v.Pointer() == 0
-	case reflect.Chan, reflect.Func, reflect.Interface, reflect.Ptr, reflect.Map, reflect.Slice:
-		return v.IsNil()
-	case reflect.Array:
-		for i := 0; i < v.Len(); i++ {
-			if !isZero(v.Index(i)) {
-				return false
-			}
-		}
-		return true
-	case reflect.Struct:
-		for i := 0; i < v.NumField(); i++ {
-			if !isZero(v.Field(i)) {
-				return false
-			}
-		}
-		return true
-	}
-	return false
-}
-
-// isExported reports whether the identifier is exported.
-func isExported(id string) bool {
-	r, _ := utf8.DecodeRuneInString(id)
-	return unicode.IsUpper(r)
-}
diff --git a/vendor/github.com/google/go-cmp/cmp/internal/value/sort.go b/vendor/github.com/google/go-cmp/cmp/internal/value/sort.go
deleted file mode 100644
index ea73cf1..0000000
--- a/vendor/github.com/google/go-cmp/cmp/internal/value/sort.go
+++ /dev/null
@@ -1,111 +0,0 @@
-// Copyright 2017, The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE.md file.
-
-package value
-
-import (
-	"fmt"
-	"math"
-	"reflect"
-	"sort"
-)
-
-// SortKeys sorts a list of map keys, deduplicating keys if necessary.
-// The type of each value must be comparable.
-func SortKeys(vs []reflect.Value) []reflect.Value {
-	if len(vs) == 0 {
-		return vs
-	}
-
-	// Sort the map keys.
-	sort.Sort(valueSorter(vs))
-
-	// Deduplicate keys (fails for NaNs).
-	vs2 := vs[:1]
-	for _, v := range vs[1:] {
-		if v.Interface() != vs2[len(vs2)-1].Interface() {
-			vs2 = append(vs2, v)
-		}
-	}
-	return vs2
-}
-
-// TODO: Use sort.Slice once Google AppEngine is on Go1.8 or above.
-type valueSorter []reflect.Value
-
-func (vs valueSorter) Len() int           { return len(vs) }
-func (vs valueSorter) Less(i, j int) bool { return isLess(vs[i], vs[j]) }
-func (vs valueSorter) Swap(i, j int)      { vs[i], vs[j] = vs[j], vs[i] }
-
-// isLess is a generic function for sorting arbitrary map keys.
-// The inputs must be of the same type and must be comparable.
-func isLess(x, y reflect.Value) bool {
-	switch x.Type().Kind() {
-	case reflect.Bool:
-		return !x.Bool() && y.Bool()
-	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
-		return x.Int() < y.Int()
-	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
-		return x.Uint() < y.Uint()
-	case reflect.Float32, reflect.Float64:
-		fx, fy := x.Float(), y.Float()
-		return fx < fy || math.IsNaN(fx) && !math.IsNaN(fy)
-	case reflect.Complex64, reflect.Complex128:
-		cx, cy := x.Complex(), y.Complex()
-		rx, ix, ry, iy := real(cx), imag(cx), real(cy), imag(cy)
-		if rx == ry || (math.IsNaN(rx) && math.IsNaN(ry)) {
-			return ix < iy || math.IsNaN(ix) && !math.IsNaN(iy)
-		}
-		return rx < ry || math.IsNaN(rx) && !math.IsNaN(ry)
-	case reflect.Ptr, reflect.UnsafePointer, reflect.Chan:
-		return x.Pointer() < y.Pointer()
-	case reflect.String:
-		return x.String() < y.String()
-	case reflect.Array:
-		for i := 0; i < x.Len(); i++ {
-			if isLess(x.Index(i), y.Index(i)) {
-				return true
-			}
-			if isLess(y.Index(i), x.Index(i)) {
-				return false
-			}
-		}
-		return false
-	case reflect.Struct:
-		for i := 0; i < x.NumField(); i++ {
-			if isLess(x.Field(i), y.Field(i)) {
-				return true
-			}
-			if isLess(y.Field(i), x.Field(i)) {
-				return false
-			}
-		}
-		return false
-	case reflect.Interface:
-		vx, vy := x.Elem(), y.Elem()
-		if !vx.IsValid() || !vy.IsValid() {
-			return !vx.IsValid() && vy.IsValid()
-		}
-		tx, ty := vx.Type(), vy.Type()
-		if tx == ty {
-			return isLess(x.Elem(), y.Elem())
-		}
-		if tx.Kind() != ty.Kind() {
-			return vx.Kind() < vy.Kind()
-		}
-		if tx.String() != ty.String() {
-			return tx.String() < ty.String()
-		}
-		if tx.PkgPath() != ty.PkgPath() {
-			return tx.PkgPath() < ty.PkgPath()
-		}
-		// This can happen in rare situations, so we fallback to just comparing
-		// the unique pointer for a reflect.Type. This guarantees deterministic
-		// ordering within a program, but it is obviously not stable.
-		return reflect.ValueOf(vx.Type()).Pointer() < reflect.ValueOf(vy.Type()).Pointer()
-	default:
-		// Must be Func, Map, or Slice; which are not comparable.
-		panic(fmt.Sprintf("%T is not comparable", x.Type()))
-	}
-}
diff --git a/vendor/github.com/google/go-cmp/cmp/options.go b/vendor/github.com/google/go-cmp/cmp/options.go
deleted file mode 100644
index a4e159a..0000000
--- a/vendor/github.com/google/go-cmp/cmp/options.go
+++ /dev/null
@@ -1,446 +0,0 @@
-// Copyright 2017, The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE.md file.
-
-package cmp
-
-import (
-	"fmt"
-	"reflect"
-	"runtime"
-	"strings"
-
-	"github.com/google/go-cmp/cmp/internal/function"
-)
-
-// Option configures for specific behavior of Equal and Diff. In particular,
-// the fundamental Option functions (Ignore, Transformer, and Comparer),
-// configure how equality is determined.
-//
-// The fundamental options may be composed with filters (FilterPath and
-// FilterValues) to control the scope over which they are applied.
-//
-// The cmp/cmpopts package provides helper functions for creating options that
-// may be used with Equal and Diff.
-type Option interface {
-	// filter applies all filters and returns the option that remains.
-	// Each option may only read s.curPath and call s.callTTBFunc.
-	//
-	// An Options is returned only if multiple comparers or transformers
-	// can apply simultaneously and will only contain values of those types
-	// or sub-Options containing values of those types.
-	filter(s *state, vx, vy reflect.Value, t reflect.Type) applicableOption
-}
-
-// applicableOption represents the following types:
-//	Fundamental: ignore | invalid | *comparer | *transformer
-//	Grouping:    Options
-type applicableOption interface {
-	Option
-
-	// apply executes the option and reports whether the option was applied.
-	// Each option may mutate s.
-	apply(s *state, vx, vy reflect.Value) bool
-}
-
-// coreOption represents the following types:
-//	Fundamental: ignore | invalid | *comparer | *transformer
-//	Filters:     *pathFilter | *valuesFilter
-type coreOption interface {
-	Option
-	isCore()
-}
-
-type core struct{}
-
-func (core) isCore() {}
-
-// Options is a list of Option values that also satisfies the Option interface.
-// Helper comparison packages may return an Options value when packing multiple
-// Option values into a single Option. When this package processes an Options,
-// it will be implicitly expanded into a flat list.
-//
-// Applying a filter on an Options is equivalent to applying that same filter
-// on all individual options held within.
-type Options []Option
-
-func (opts Options) filter(s *state, vx, vy reflect.Value, t reflect.Type) (out applicableOption) {
-	for _, opt := range opts {
-		switch opt := opt.filter(s, vx, vy, t); opt.(type) {
-		case ignore:
-			return ignore{} // Only ignore can short-circuit evaluation
-		case invalid:
-			out = invalid{} // Takes precedence over comparer or transformer
-		case *comparer, *transformer, Options:
-			switch out.(type) {
-			case nil:
-				out = opt
-			case invalid:
-				// Keep invalid
-			case *comparer, *transformer, Options:
-				out = Options{out, opt} // Conflicting comparers or transformers
-			}
-		}
-	}
-	return out
-}
-
-func (opts Options) apply(s *state, _, _ reflect.Value) bool {
-	const warning = "ambiguous set of applicable options"
-	const help = "consider using filters to ensure at most one Comparer or Transformer may apply"
-	var ss []string
-	for _, opt := range flattenOptions(nil, opts) {
-		ss = append(ss, fmt.Sprint(opt))
-	}
-	set := strings.Join(ss, "\n\t")
-	panic(fmt.Sprintf("%s at %#v:\n\t%s\n%s", warning, s.curPath, set, help))
-}
-
-func (opts Options) String() string {
-	var ss []string
-	for _, opt := range opts {
-		ss = append(ss, fmt.Sprint(opt))
-	}
-	return fmt.Sprintf("Options{%s}", strings.Join(ss, ", "))
-}
-
-// FilterPath returns a new Option where opt is only evaluated if filter f
-// returns true for the current Path in the value tree.
-//
-// The option passed in may be an Ignore, Transformer, Comparer, Options, or
-// a previously filtered Option.
-func FilterPath(f func(Path) bool, opt Option) Option {
-	if f == nil {
-		panic("invalid path filter function")
-	}
-	if opt := normalizeOption(opt); opt != nil {
-		return &pathFilter{fnc: f, opt: opt}
-	}
-	return nil
-}
-
-type pathFilter struct {
-	core
-	fnc func(Path) bool
-	opt Option
-}
-
-func (f pathFilter) filter(s *state, vx, vy reflect.Value, t reflect.Type) applicableOption {
-	if f.fnc(s.curPath) {
-		return f.opt.filter(s, vx, vy, t)
-	}
-	return nil
-}
-
-func (f pathFilter) String() string {
-	fn := getFuncName(reflect.ValueOf(f.fnc).Pointer())
-	return fmt.Sprintf("FilterPath(%s, %v)", fn, f.opt)
-}
-
-// FilterValues returns a new Option where opt is only evaluated if filter f,
-// which is a function of the form "func(T, T) bool", returns true for the
-// current pair of values being compared. If the type of the values is not
-// assignable to T, then this filter implicitly returns false.
-//
-// The filter function must be
-// symmetric (i.e., agnostic to the order of the inputs) and
-// deterministic (i.e., produces the same result when given the same inputs).
-// If T is an interface, it is possible that f is called with two values with
-// different concrete types that both implement T.
-//
-// The option passed in may be an Ignore, Transformer, Comparer, Options, or
-// a previously filtered Option.
-func FilterValues(f interface{}, opt Option) Option {
-	v := reflect.ValueOf(f)
-	if !function.IsType(v.Type(), function.ValueFilter) || v.IsNil() {
-		panic(fmt.Sprintf("invalid values filter function: %T", f))
-	}
-	if opt := normalizeOption(opt); opt != nil {
-		vf := &valuesFilter{fnc: v, opt: opt}
-		if ti := v.Type().In(0); ti.Kind() != reflect.Interface || ti.NumMethod() > 0 {
-			vf.typ = ti
-		}
-		return vf
-	}
-	return nil
-}
-
-type valuesFilter struct {
-	core
-	typ reflect.Type  // T
-	fnc reflect.Value // func(T, T) bool
-	opt Option
-}
-
-func (f valuesFilter) filter(s *state, vx, vy reflect.Value, t reflect.Type) applicableOption {
-	if !vx.IsValid() || !vy.IsValid() {
-		return invalid{}
-	}
-	if (f.typ == nil || t.AssignableTo(f.typ)) && s.callTTBFunc(f.fnc, vx, vy) {
-		return f.opt.filter(s, vx, vy, t)
-	}
-	return nil
-}
-
-func (f valuesFilter) String() string {
-	fn := getFuncName(f.fnc.Pointer())
-	return fmt.Sprintf("FilterValues(%s, %v)", fn, f.opt)
-}
-
-// Ignore is an Option that causes all comparisons to be ignored.
-// This value is intended to be combined with FilterPath or FilterValues.
-// It is an error to pass an unfiltered Ignore option to Equal.
-func Ignore() Option { return ignore{} }
-
-type ignore struct{ core }
-
-func (ignore) isFiltered() bool                                                     { return false }
-func (ignore) filter(_ *state, _, _ reflect.Value, _ reflect.Type) applicableOption { return ignore{} }
-func (ignore) apply(_ *state, _, _ reflect.Value) bool                              { return true }
-func (ignore) String() string                                                       { return "Ignore()" }
-
-// invalid is a sentinel Option type to indicate that some options could not
-// be evaluated due to unexported fields.
-type invalid struct{ core }
-
-func (invalid) filter(_ *state, _, _ reflect.Value, _ reflect.Type) applicableOption { return invalid{} }
-func (invalid) apply(s *state, _, _ reflect.Value) bool {
-	const help = "consider using AllowUnexported or cmpopts.IgnoreUnexported"
-	panic(fmt.Sprintf("cannot handle unexported field: %#v\n%s", s.curPath, help))
-}
-
-// Transformer returns an Option that applies a transformation function that
-// converts values of a certain type into that of another.
-//
-// The transformer f must be a function "func(T) R" that converts values of
-// type T to those of type R and is implicitly filtered to input values
-// assignable to T. The transformer must not mutate T in any way.
-// If T and R are the same type, an additional filter must be applied to
-// act as the base case to prevent an infinite recursion applying the same
-// transform to itself (see the SortedSlice example).
-//
-// The name is a user provided label that is used as the Transform.Name in the
-// transformation PathStep. If empty, an arbitrary name is used.
-func Transformer(name string, f interface{}) Option {
-	v := reflect.ValueOf(f)
-	if !function.IsType(v.Type(), function.Transformer) || v.IsNil() {
-		panic(fmt.Sprintf("invalid transformer function: %T", f))
-	}
-	if name == "" {
-		name = "λ" // Lambda-symbol as place-holder for anonymous transformer
-	}
-	if !isValid(name) {
-		panic(fmt.Sprintf("invalid name: %q", name))
-	}
-	tr := &transformer{name: name, fnc: reflect.ValueOf(f)}
-	if ti := v.Type().In(0); ti.Kind() != reflect.Interface || ti.NumMethod() > 0 {
-		tr.typ = ti
-	}
-	return tr
-}
-
-type transformer struct {
-	core
-	name string
-	typ  reflect.Type  // T
-	fnc  reflect.Value // func(T) R
-}
-
-func (tr *transformer) isFiltered() bool { return tr.typ != nil }
-
-func (tr *transformer) filter(_ *state, _, _ reflect.Value, t reflect.Type) applicableOption {
-	if tr.typ == nil || t.AssignableTo(tr.typ) {
-		return tr
-	}
-	return nil
-}
-
-func (tr *transformer) apply(s *state, vx, vy reflect.Value) bool {
-	// Update path before calling the Transformer so that dynamic checks
-	// will use the updated path.
-	s.curPath.push(&transform{pathStep{tr.fnc.Type().Out(0)}, tr})
-	defer s.curPath.pop()
-
-	vx = s.callTRFunc(tr.fnc, vx)
-	vy = s.callTRFunc(tr.fnc, vy)
-	s.compareAny(vx, vy)
-	return true
-}
-
-func (tr transformer) String() string {
-	return fmt.Sprintf("Transformer(%s, %s)", tr.name, getFuncName(tr.fnc.Pointer()))
-}
-
-// Comparer returns an Option that determines whether two values are equal
-// to each other.
-//
-// The comparer f must be a function "func(T, T) bool" and is implicitly
-// filtered to input values assignable to T. If T is an interface, it is
-// possible that f is called with two values of different concrete types that
-// both implement T.
-//
-// The equality function must be:
-//	• Symmetric: equal(x, y) == equal(y, x)
-//	• Deterministic: equal(x, y) == equal(x, y)
-//	• Pure: equal(x, y) does not modify x or y
-func Comparer(f interface{}) Option {
-	v := reflect.ValueOf(f)
-	if !function.IsType(v.Type(), function.Equal) || v.IsNil() {
-		panic(fmt.Sprintf("invalid comparer function: %T", f))
-	}
-	cm := &comparer{fnc: v}
-	if ti := v.Type().In(0); ti.Kind() != reflect.Interface || ti.NumMethod() > 0 {
-		cm.typ = ti
-	}
-	return cm
-}
-
-type comparer struct {
-	core
-	typ reflect.Type  // T
-	fnc reflect.Value // func(T, T) bool
-}
-
-func (cm *comparer) isFiltered() bool { return cm.typ != nil }
-
-func (cm *comparer) filter(_ *state, _, _ reflect.Value, t reflect.Type) applicableOption {
-	if cm.typ == nil || t.AssignableTo(cm.typ) {
-		return cm
-	}
-	return nil
-}
-
-func (cm *comparer) apply(s *state, vx, vy reflect.Value) bool {
-	eq := s.callTTBFunc(cm.fnc, vx, vy)
-	s.report(eq, vx, vy)
-	return true
-}
-
-func (cm comparer) String() string {
-	return fmt.Sprintf("Comparer(%s)", getFuncName(cm.fnc.Pointer()))
-}
-
-// AllowUnexported returns an Option that forcibly allows operations on
-// unexported fields in certain structs, which are specified by passing in a
-// value of each struct type.
-//
-// Users of this option must understand that comparing on unexported fields
-// from external packages is not safe since changes in the internal
-// implementation of some external package may cause the result of Equal
-// to unexpectedly change. However, it may be valid to use this option on types
-// defined in an internal package where the semantic meaning of an unexported
-// field is in the control of the user.
-//
-// For some cases, a custom Comparer should be used instead that defines
-// equality as a function of the public API of a type rather than the underlying
-// unexported implementation.
-//
-// For example, the reflect.Type documentation defines equality to be determined
-// by the == operator on the interface (essentially performing a shallow pointer
-// comparison) and most attempts to compare *regexp.Regexp types are interested
-// in only checking that the regular expression strings are equal.
-// Both of these are accomplished using Comparers:
-//
-//	Comparer(func(x, y reflect.Type) bool { return x == y })
-//	Comparer(func(x, y *regexp.Regexp) bool { return x.String() == y.String() })
-//
-// In other cases, the cmpopts.IgnoreUnexported option can be used to ignore
-// all unexported fields on specified struct types.
-func AllowUnexported(types ...interface{}) Option {
-	if !supportAllowUnexported {
-		panic("AllowUnexported is not supported on App Engine Classic or GopherJS")
-	}
-	m := make(map[reflect.Type]bool)
-	for _, typ := range types {
-		t := reflect.TypeOf(typ)
-		if t.Kind() != reflect.Struct {
-			panic(fmt.Sprintf("invalid struct type: %T", typ))
-		}
-		m[t] = true
-	}
-	return visibleStructs(m)
-}
-
-type visibleStructs map[reflect.Type]bool
-
-func (visibleStructs) filter(_ *state, _, _ reflect.Value, _ reflect.Type) applicableOption {
-	panic("not implemented")
-}
-
-// reporter is an Option that configures how differences are reported.
-type reporter interface {
-	// TODO: Not exported yet.
-	//
-	// Perhaps add PushStep and PopStep and change Report to only accept
-	// a PathStep instead of the full-path? Adding a PushStep and PopStep makes
-	// it clear that we are traversing the value tree in a depth-first-search
-	// manner, which has an effect on how values are printed.
-
-	Option
-
-	// Report is called for every comparison made and will be provided with
-	// the two values being compared, the equality result, and the
-	// current path in the value tree. It is possible for x or y to be an
-	// invalid reflect.Value if one of the values is non-existent;
-	// which is possible with maps and slices.
-	Report(x, y reflect.Value, eq bool, p Path)
-}
-
-// normalizeOption normalizes the input options such that all Options groups
-// are flattened and groups with a single element are reduced to that element.
-// Only coreOptions and Options containing coreOptions are allowed.
-func normalizeOption(src Option) Option {
-	switch opts := flattenOptions(nil, Options{src}); len(opts) {
-	case 0:
-		return nil
-	case 1:
-		return opts[0]
-	default:
-		return opts
-	}
-}
-
-// flattenOptions copies all options in src to dst as a flat list.
-// Only coreOptions and Options containing coreOptions are allowed.
-func flattenOptions(dst, src Options) Options {
-	for _, opt := range src {
-		switch opt := opt.(type) {
-		case nil:
-			continue
-		case Options:
-			dst = flattenOptions(dst, opt)
-		case coreOption:
-			dst = append(dst, opt)
-		default:
-			panic(fmt.Sprintf("invalid option type: %T", opt))
-		}
-	}
-	return dst
-}
-
-// getFuncName returns a short function name from the pointer.
-// The string parsing logic works up until Go1.9.
-func getFuncName(p uintptr) string {
-	fnc := runtime.FuncForPC(p)
-	if fnc == nil {
-		return "<unknown>"
-	}
-	name := fnc.Name() // E.g., "long/path/name/mypkg.(mytype).(long/path/name/mypkg.myfunc)-fm"
-	if strings.HasSuffix(name, ")-fm") || strings.HasSuffix(name, ")·fm") {
-		// Strip the package name from method name.
-		name = strings.TrimSuffix(name, ")-fm")
-		name = strings.TrimSuffix(name, ")·fm")
-		if i := strings.LastIndexByte(name, '('); i >= 0 {
-			methodName := name[i+1:] // E.g., "long/path/name/mypkg.myfunc"
-			if j := strings.LastIndexByte(methodName, '.'); j >= 0 {
-				methodName = methodName[j+1:] // E.g., "myfunc"
-			}
-			name = name[:i] + methodName // E.g., "long/path/name/mypkg.(mytype)." + "myfunc"
-		}
-	}
-	if i := strings.LastIndexByte(name, '/'); i >= 0 {
-		// Strip the package name.
-		name = name[i+1:] // E.g., "mypkg.(mytype).myfunc"
-	}
-	return name
-}
diff --git a/vendor/github.com/google/go-cmp/cmp/path.go b/vendor/github.com/google/go-cmp/cmp/path.go
deleted file mode 100644
index 0c2eb33..0000000
--- a/vendor/github.com/google/go-cmp/cmp/path.go
+++ /dev/null
@@ -1,293 +0,0 @@
-// Copyright 2017, The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE.md file.
-
-package cmp
-
-import (
-	"fmt"
-	"reflect"
-	"strings"
-	"unicode"
-	"unicode/utf8"
-)
-
-type (
-	// Path is a list of PathSteps describing the sequence of operations to get
-	// from some root type to the current position in the value tree.
-	// The first Path element is always an operation-less PathStep that exists
-	// simply to identify the initial type.
-	//
-	// When traversing structs with embedded structs, the embedded struct will
-	// always be accessed as a field before traversing the fields of the
-	// embedded struct themselves. That is, an exported field from the
-	// embedded struct will never be accessed directly from the parent struct.
-	Path []PathStep
-
-	// PathStep is a union-type for specific operations to traverse
-	// a value's tree structure. Users of this package never need to implement
-	// these types as values of this type will be returned by this package.
-	PathStep interface {
-		String() string
-		Type() reflect.Type // Resulting type after performing the path step
-		isPathStep()
-	}
-
-	// SliceIndex is an index operation on a slice or array at some index Key.
-	SliceIndex interface {
-		PathStep
-		Key() int // May return -1 if in a split state
-
-		// SplitKeys returns the indexes for indexing into slices in the
-		// x and y values, respectively. These indexes may differ due to the
-		// insertion or removal of an element in one of the slices, causing
-		// all of the indexes to be shifted. If an index is -1, then that
-		// indicates that the element does not exist in the associated slice.
-		//
-		// Key is guaranteed to return -1 if and only if the indexes returned
-		// by SplitKeys are not the same. SplitKeys will never return -1 for
-		// both indexes.
-		SplitKeys() (x int, y int)
-
-		isSliceIndex()
-	}
-	// MapIndex is an index operation on a map at some index Key.
-	MapIndex interface {
-		PathStep
-		Key() reflect.Value
-		isMapIndex()
-	}
-	// TypeAssertion represents a type assertion on an interface.
-	TypeAssertion interface {
-		PathStep
-		isTypeAssertion()
-	}
-	// StructField represents a struct field access on a field called Name.
-	StructField interface {
-		PathStep
-		Name() string
-		Index() int
-		isStructField()
-	}
-	// Indirect represents pointer indirection on the parent type.
-	Indirect interface {
-		PathStep
-		isIndirect()
-	}
-	// Transform is a transformation from the parent type to the current type.
-	Transform interface {
-		PathStep
-		Name() string
-		Func() reflect.Value
-		isTransform()
-	}
-)
-
-func (pa *Path) push(s PathStep) {
-	*pa = append(*pa, s)
-}
-
-func (pa *Path) pop() {
-	*pa = (*pa)[:len(*pa)-1]
-}
-
-// Last returns the last PathStep in the Path.
-// If the path is empty, this returns a non-nil PathStep that reports a nil Type.
-func (pa Path) Last() PathStep {
-	if len(pa) > 0 {
-		return pa[len(pa)-1]
-	}
-	return pathStep{}
-}
-
-// String returns the simplified path to a node.
-// The simplified path only contains struct field accesses.
-//
-// For example:
-//	MyMap.MySlices.MyField
-func (pa Path) String() string {
-	var ss []string
-	for _, s := range pa {
-		if _, ok := s.(*structField); ok {
-			ss = append(ss, s.String())
-		}
-	}
-	return strings.TrimPrefix(strings.Join(ss, ""), ".")
-}
-
-// GoString returns the path to a specific node using Go syntax.
-//
-// For example:
-//	(*root.MyMap["key"].(*mypkg.MyStruct).MySlices)[2][3].MyField
-func (pa Path) GoString() string {
-	var ssPre, ssPost []string
-	var numIndirect int
-	for i, s := range pa {
-		var nextStep PathStep
-		if i+1 < len(pa) {
-			nextStep = pa[i+1]
-		}
-		switch s := s.(type) {
-		case *indirect:
-			numIndirect++
-			pPre, pPost := "(", ")"
-			switch nextStep.(type) {
-			case *indirect:
-				continue // Next step is indirection, so let them batch up
-			case *structField:
-				numIndirect-- // Automatic indirection on struct fields
-			case nil:
-				pPre, pPost = "", "" // Last step; no need for parenthesis
-			}
-			if numIndirect > 0 {
-				ssPre = append(ssPre, pPre+strings.Repeat("*", numIndirect))
-				ssPost = append(ssPost, pPost)
-			}
-			numIndirect = 0
-			continue
-		case *transform:
-			ssPre = append(ssPre, s.trans.name+"(")
-			ssPost = append(ssPost, ")")
-			continue
-		case *typeAssertion:
-			// Elide type assertions immediately following a transform to
-			// prevent overly verbose path printouts.
-			// Some transforms return interface{} because of Go's lack of
-			// generics, but typically take in and return the exact same
-			// concrete type. Other times, the transform creates an anonymous
-			// struct, which will be very verbose to print.
-			if _, ok := nextStep.(*transform); ok {
-				continue
-			}
-		}
-		ssPost = append(ssPost, s.String())
-	}
-	for i, j := 0, len(ssPre)-1; i < j; i, j = i+1, j-1 {
-		ssPre[i], ssPre[j] = ssPre[j], ssPre[i]
-	}
-	return strings.Join(ssPre, "") + strings.Join(ssPost, "")
-}
-
-type (
-	pathStep struct {
-		typ reflect.Type
-	}
-
-	sliceIndex struct {
-		pathStep
-		xkey, ykey int
-	}
-	mapIndex struct {
-		pathStep
-		key reflect.Value
-	}
-	typeAssertion struct {
-		pathStep
-	}
-	structField struct {
-		pathStep
-		name string
-		idx  int
-
-		// These fields are used for forcibly accessing an unexported field.
-		// pvx, pvy, and field are only valid if unexported is true.
-		unexported bool
-		force      bool                // Forcibly allow visibility
-		pvx, pvy   reflect.Value       // Parent values
-		field      reflect.StructField // Field information
-	}
-	indirect struct {
-		pathStep
-	}
-	transform struct {
-		pathStep
-		trans *transformer
-	}
-)
-
-func (ps pathStep) Type() reflect.Type { return ps.typ }
-func (ps pathStep) String() string {
-	if ps.typ == nil {
-		return "<nil>"
-	}
-	s := ps.typ.String()
-	if s == "" || strings.ContainsAny(s, "{}\n") {
-		return "root" // Type too simple or complex to print
-	}
-	return fmt.Sprintf("{%s}", s)
-}
-
-func (si sliceIndex) String() string {
-	switch {
-	case si.xkey == si.ykey:
-		return fmt.Sprintf("[%d]", si.xkey)
-	case si.ykey == -1:
-		// [5->?] means "I don't know where X[5] went"
-		return fmt.Sprintf("[%d->?]", si.xkey)
-	case si.xkey == -1:
-		// [?->3] means "I don't know where Y[3] came from"
-		return fmt.Sprintf("[?->%d]", si.ykey)
-	default:
-		// [5->3] means "X[5] moved to Y[3]"
-		return fmt.Sprintf("[%d->%d]", si.xkey, si.ykey)
-	}
-}
-func (mi mapIndex) String() string      { return fmt.Sprintf("[%#v]", mi.key) }
-func (ta typeAssertion) String() string { return fmt.Sprintf(".(%v)", ta.typ) }
-func (sf structField) String() string   { return fmt.Sprintf(".%s", sf.name) }
-func (in indirect) String() string      { return "*" }
-func (tf transform) String() string     { return fmt.Sprintf("%s()", tf.trans.name) }
-
-func (si sliceIndex) Key() int {
-	if si.xkey != si.ykey {
-		return -1
-	}
-	return si.xkey
-}
-func (si sliceIndex) SplitKeys() (x, y int) { return si.xkey, si.ykey }
-func (mi mapIndex) Key() reflect.Value      { return mi.key }
-func (sf structField) Name() string         { return sf.name }
-func (sf structField) Index() int           { return sf.idx }
-func (tf transform) Name() string           { return tf.trans.name }
-func (tf transform) Func() reflect.Value    { return tf.trans.fnc }
-
-func (pathStep) isPathStep()           {}
-func (sliceIndex) isSliceIndex()       {}
-func (mapIndex) isMapIndex()           {}
-func (typeAssertion) isTypeAssertion() {}
-func (structField) isStructField()     {}
-func (indirect) isIndirect()           {}
-func (transform) isTransform()         {}
-
-var (
-	_ SliceIndex    = sliceIndex{}
-	_ MapIndex      = mapIndex{}
-	_ TypeAssertion = typeAssertion{}
-	_ StructField   = structField{}
-	_ Indirect      = indirect{}
-	_ Transform     = transform{}
-
-	_ PathStep = sliceIndex{}
-	_ PathStep = mapIndex{}
-	_ PathStep = typeAssertion{}
-	_ PathStep = structField{}
-	_ PathStep = indirect{}
-	_ PathStep = transform{}
-)
-
-// isExported reports whether the identifier is exported.
-func isExported(id string) bool {
-	r, _ := utf8.DecodeRuneInString(id)
-	return unicode.IsUpper(r)
-}
-
-// isValid reports whether the identifier is valid.
-// Empty and underscore-only strings are not valid.
-func isValid(id string) bool {
-	ok := id != "" && id != "_"
-	for j, c := range id {
-		ok = ok && (j > 0 || !unicode.IsDigit(c))
-		ok = ok && (c == '_' || unicode.IsLetter(c) || unicode.IsDigit(c))
-	}
-	return ok
-}
diff --git a/vendor/github.com/google/go-cmp/cmp/reporter.go b/vendor/github.com/google/go-cmp/cmp/reporter.go
deleted file mode 100644
index a21d0cd..0000000
--- a/vendor/github.com/google/go-cmp/cmp/reporter.go
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2017, The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE.md file.
-
-package cmp
-
-import (
-	"fmt"
-	"reflect"
-	"strings"
-
-	"github.com/google/go-cmp/cmp/internal/value"
-)
-
-type defaultReporter struct {
-	Option
-	diffs  []string // List of differences, possibly truncated
-	ndiffs int      // Total number of differences
-	nbytes int      // Number of bytes in diffs
-	nlines int      // Number of lines in diffs
-}
-
-var _ reporter = (*defaultReporter)(nil)
-
-func (r *defaultReporter) Report(x, y reflect.Value, eq bool, p Path) {
-	if eq {
-		return // Ignore equal results
-	}
-	const maxBytes = 4096
-	const maxLines = 256
-	r.ndiffs++
-	if r.nbytes < maxBytes && r.nlines < maxLines {
-		sx := value.Format(x, true)
-		sy := value.Format(y, true)
-		if sx == sy {
-			// Stringer is not helpful, so rely on more exact formatting.
-			sx = value.Format(x, false)
-			sy = value.Format(y, false)
-		}
-		s := fmt.Sprintf("%#v:\n\t-: %s\n\t+: %s\n", p, sx, sy)
-		r.diffs = append(r.diffs, s)
-		r.nbytes += len(s)
-		r.nlines += strings.Count(s, "\n")
-	}
-}
-
-func (r *defaultReporter) String() string {
-	s := strings.Join(r.diffs, "")
-	if r.ndiffs == len(r.diffs) {
-		return s
-	}
-	return fmt.Sprintf("%s... %d more differences ...", s, len(r.diffs)-r.ndiffs)
-}
diff --git a/vendor/github.com/google/go-cmp/cmp/unsafe_panic.go b/vendor/github.com/google/go-cmp/cmp/unsafe_panic.go
deleted file mode 100644
index 0d44987..0000000
--- a/vendor/github.com/google/go-cmp/cmp/unsafe_panic.go
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2017, The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE.md file.
-
-// +build appengine js
-
-package cmp
-
-import "reflect"
-
-const supportAllowUnexported = false
-
-func unsafeRetrieveField(reflect.Value, reflect.StructField) reflect.Value {
-	panic("unsafeRetrieveField is not implemented")
-}
diff --git a/vendor/github.com/google/go-cmp/cmp/unsafe_reflect.go b/vendor/github.com/google/go-cmp/cmp/unsafe_reflect.go
deleted file mode 100644
index 81fb826..0000000
--- a/vendor/github.com/google/go-cmp/cmp/unsafe_reflect.go
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2017, The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE.md file.
-
-// +build !appengine,!js
-
-package cmp
-
-import (
-	"reflect"
-	"unsafe"
-)
-
-const supportAllowUnexported = true
-
-// unsafeRetrieveField uses unsafe to forcibly retrieve any field from a struct
-// such that the value has read-write permissions.
-//
-// The parent struct, v, must be addressable, while f must be a StructField
-// describing the field to retrieve.
-func unsafeRetrieveField(v reflect.Value, f reflect.StructField) reflect.Value {
-	return reflect.NewAt(f.Type, unsafe.Pointer(v.UnsafeAddr()+f.Offset)).Elem()
-}
diff --git a/vendor/github.com/pkg/errors/.gitignore b/vendor/github.com/pkg/errors/.gitignore
deleted file mode 100644
index daf913b..0000000
--- a/vendor/github.com/pkg/errors/.gitignore
+++ /dev/null
@@ -1,24 +0,0 @@
-# Compiled Object files, Static and Dynamic libs (Shared Objects)
-*.o
-*.a
-*.so
-
-# Folders
-_obj
-_test
-
-# Architecture specific extensions/prefixes
-*.[568vq]
-[568vq].out
-
-*.cgo1.go
-*.cgo2.c
-_cgo_defun.c
-_cgo_gotypes.go
-_cgo_export.*
-
-_testmain.go
-
-*.exe
-*.test
-*.prof
diff --git a/vendor/github.com/pkg/errors/.travis.yml b/vendor/github.com/pkg/errors/.travis.yml
deleted file mode 100644
index 588ceca..0000000
--- a/vendor/github.com/pkg/errors/.travis.yml
+++ /dev/null
@@ -1,11 +0,0 @@
-language: go
-go_import_path: github.com/pkg/errors
-go:
-  - 1.4.3
-  - 1.5.4
-  - 1.6.2
-  - 1.7.1
-  - tip
-
-script:
-  - go test -v ./...
diff --git a/vendor/github.com/pkg/errors/LICENSE b/vendor/github.com/pkg/errors/LICENSE
deleted file mode 100644
index 835ba3e..0000000
--- a/vendor/github.com/pkg/errors/LICENSE
+++ /dev/null
@@ -1,23 +0,0 @@
-Copyright (c) 2015, Dave Cheney <dave@cheney.net>
-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/README.md b/vendor/github.com/pkg/errors/README.md
deleted file mode 100644
index 273db3c..0000000
--- a/vendor/github.com/pkg/errors/README.md
+++ /dev/null
@@ -1,52 +0,0 @@
-# errors [![Travis-CI](https://travis-ci.org/pkg/errors.svg)](https://travis-ci.org/pkg/errors) [![AppVeyor](https://ci.appveyor.com/api/projects/status/b98mptawhudj53ep/branch/master?svg=true)](https://ci.appveyor.com/project/davecheney/errors/branch/master) [![GoDoc](https://godoc.org/github.com/pkg/errors?status.svg)](http://godoc.org/github.com/pkg/errors) [![Report card](https://goreportcard.com/badge/github.com/pkg/errors)](https://goreportcard.com/report/github.com/pkg/errors)
-
-Package errors provides simple error handling primitives.
-
-`go get github.com/pkg/errors`
-
-The traditional error handling idiom in Go is roughly akin to
-```go
-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. For example
-```go
-_, err := ioutil.ReadAll(r)
-if err != nil {
-        return errors.Wrap(err, "read failed")
-}
-```
-## 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 can be inspected by `errors.Cause`.
-```go
-type causer interface {
-        Cause() error
-}
-```
-`errors.Cause` will recursively retrieve the topmost error which does not implement `causer`, which is assumed to be the original cause. For example:
-```go
-switch err := errors.Cause(err).(type) {
-case *MyError:
-        // handle specifically
-default:
-        // unknown error
-}
-```
-
-[Read the package documentation for more information](https://godoc.org/github.com/pkg/errors).
-
-## Contributing
-
-We welcome pull requests, bug fixes and issue reports. With that said, the bar for adding new symbols to this package is intentionally set high.
-
-Before proposing a change, please discuss your change by raising an issue.
-
-## Licence
-
-BSD-2-Clause
diff --git a/vendor/github.com/pkg/errors/appveyor.yml b/vendor/github.com/pkg/errors/appveyor.yml
deleted file mode 100644
index a932ead..0000000
--- a/vendor/github.com/pkg/errors/appveyor.yml
+++ /dev/null
@@ -1,32 +0,0 @@
-version: build-{build}.{branch}
-
-clone_folder: C:\gopath\src\github.com\pkg\errors
-shallow_clone: true # for startup speed
-
-environment:
-  GOPATH: C:\gopath
-
-platform:
-  - x64
-
-# http://www.appveyor.com/docs/installed-software
-install:
-  # some helpful output for debugging builds
-  - go version
-  - go env
-  # pre-installed MinGW at C:\MinGW is 32bit only
-  # but MSYS2 at C:\msys64 has mingw64
-  - set PATH=C:\msys64\mingw64\bin;%PATH%
-  - gcc --version
-  - g++ --version
-
-build_script:
-  - go install -v ./...
-
-test_script:
-  - set PATH=C:\gopath\bin;%PATH%
-  - go test -v ./...
-
-#artifacts:
-#  - path: '%GOPATH%\bin\*.exe'
-deploy: off
diff --git a/vendor/github.com/pkg/errors/errors.go b/vendor/github.com/pkg/errors/errors.go
deleted file mode 100644
index 842ee80..0000000
--- a/vendor/github.com/pkg/errors/errors.go
+++ /dev/null
@@ -1,269 +0,0 @@
-// 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
deleted file mode 100644
index 6b1f289..0000000
--- a/vendor/github.com/pkg/errors/stack.go
+++ /dev/null
@@ -1,178 +0,0 @@
-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
-}


Test patch:
diff --git a/mage/main_test.go b/mage/main_test.go
index da702bd..ce32430 100644
--- a/mage/main_test.go
+++ b/mage/main_test.go
@@ -7,6 +7,8 @@ import (
 	"os/exec"
 	"path/filepath"
 	"testing"
+
+	"github.com/magefile/mage/mg"
 )
 
 func TestMain(m *testing.M) {
@@ -21,7 +23,7 @@ func testmain(m *testing.M) int {
 	if err != nil {
 		log.Fatal(err)
 	}
-	if err := os.Setenv(CacheEnv, abs); err != nil {
+	if err := os.Setenv(mg.CacheEnv, abs); err != nil {
 		log.Fatal(err)
 	}
 	if err := os.Mkdir(dir, 0700); err != nil {
@@ -46,6 +48,33 @@ func TestGoRun(t *testing.T) {
 	}
 }
 
+func TestVerbose(t *testing.T) {
+	c := exec.Command("go", "run", "main.go", "testverbose")
+	c.Dir = "./testdata"
+	c.Env = os.Environ()
+	b, err := c.CombinedOutput()
+	if err != nil {
+		t.Error("error:", err)
+	}
+	actual := string(b)
+	expected := ""
+	if actual != expected {
+		t.Fatalf("expected %q, but got %q", expected, actual)
+	}
+	c = exec.Command("go", "run", "main.go", "-v", "testverbose")
+	c.Dir = "./testdata"
+	c.Env = os.Environ()
+	b, err = c.CombinedOutput()
+	if err != nil {
+		t.Error("error:", err)
+	}
+	actual = string(b)
+	expected = "hi!\n"
+	if actual != expected {
+		t.Fatalf("expected %q, but got %q", expected, actual)
+	}
+}
+
 // ensure we include the hash of the mainfile template in determining the
 // executable name to run, so we automatically create a new exe if the template
 // changes.
diff --git a/mage/testdata/command.go b/mage/testdata/command.go
index fd071ad..951835d 100644
--- a/mage/testdata/command.go
+++ b/mage/testdata/command.go
@@ -4,6 +4,7 @@ package main
 
 import (
 	"fmt"
+	"log"
 
 	"github.com/magefile/mage/mg"
 )
@@ -17,6 +18,10 @@ func ReturnsString() string {
 	return ""
 }
 
+func TestVerbose() {
+	log.Println("hi!")
+}
+
 func ReturnsVoid() {
 	mg.Deps(f)
 }
diff --git a/mage/testdata/func.go b/mage/testdata/func.go
index 824d642..7e8f386 100644
--- a/mage/testdata/func.go
+++ b/mage/testdata/func.go
@@ -2,7 +2,9 @@
 
 package main
 
-import "fmt"
+import (
+	"fmt"
+)
 
 // Synopsis for returns error.
 // And some more text.
diff --git a/mg/deps_test.go b/mg/deps_test.go
index 7ca1cdd..0c4ea46 100644
--- a/mg/deps_test.go
+++ b/mg/deps_test.go
@@ -1,12 +1,12 @@
 package mg_test
 
 import (
+	"errors"
 	"fmt"
 	"testing"
 	"time"
 
 	"github.com/magefile/mage/mg"
-	"github.com/pkg/errors"
 )
 
 func TestDepsRunOnce(t *testing.T) {
diff --git a/parse/parse_test.go b/parse/parse_test.go
index 58139e1..def1000 100644
--- a/parse/parse_test.go
+++ b/parse/parse_test.go
@@ -1,9 +1,8 @@
 package parse
 
 import (
+	"reflect"
 	"testing"
-
-	"github.com/google/go-cmp/cmp"
 )
 
 func TestParse(t *testing.T) {
@@ -27,8 +26,9 @@ func TestParse(t *testing.T) {
 		DefaultIsError: true,
 		DefaultName:    "ReturnsError",
 	}
-	diff := cmp.Diff(expected, *info)
-	if diff != "" {
-		t.Error(diff)
+
+	// TODO: Don't use DeepEqual, you lazy git!
+	if !reflect.DeepEqual(expected, *info) {
+		t.Fatalf("expected:\n%#v\n\ngot:\n%#v", expected, *info)
 	}
 }
diff --git a/sh/cmd_test.go b/sh/cmd_test.go
new file mode 100644
index 0000000..0edc002
--- /dev/null
+++ b/sh/cmd_test.go
@@ -0,0 +1,79 @@
+package sh
+
+import (
+	"bytes"
+	"os"
+	"testing"
+)
+
+func TestOutCmd(t *testing.T) {
+	cmd := OutCmd(os.Args[0], "-printArgs", "foo", "bar")
+	out, err := cmd("baz", "bat")
+	if err != nil {
+		t.Fatal(err)
+	}
+	expected := "[foo bar baz bat]"
+	if out != expected {
+		t.Fatalf("expected %q but got %q", expected, out)
+	}
+}
+
+func TestExitCode(t *testing.T) {
+	ran, err := Exec(nil, nil, os.Args[0], "-helper", "-exit", "99")
+	if err == nil {
+		t.Fatal("unexpected nil error from run")
+	}
+	if !ran {
+		t.Errorf("ran returned as false, but should have been true")
+	}
+	code := ExitStatus(err)
+	if code != 99 {
+		t.Fatalf("expected exit status 99, but got %v", code)
+	}
+}
+
+func TestEnv(t *testing.T) {
+	env := "SOME_REALLY_LONG_MAGEFILE_SPECIFIC_THING"
+	out := &bytes.Buffer{}
+	ran, err := Exec(map[string]string{env: "foobar"}, out, os.Args[0], "-printVar", env)
+	if err != nil {
+		t.Fatalf("unexpected error from runner: %#v", err)
+	}
+	if !ran {
+		t.Errorf("expected ran to be true but was false.")
+	}
+	if out.String() != "foobar\n" {
+		t.Errorf("expected foobar, got %q", out)
+	}
+}
+
+func TestNotRun(t *testing.T) {
+	ran, err := Exec(nil, nil, "thiswontwork")
+	if err == nil {
+		t.Fatal("unexpected nil error")
+	}
+	if ran {
+		t.Fatal("expected ran to be false but was true")
+	}
+}
+
+func TestAutoExpand(t *testing.T) {
+	if err := os.Setenv("MAGE_FOOBAR", "baz"); err != nil {
+		t.Fatal(err)
+	}
+	s, err := Output("echo", "$MAGE_FOOBAR")
+	if err != nil {
+		t.Fatal(err)
+	}
+	if s != "baz" {
+		t.Fatalf(`Expected "baz" but got %q`, s)
+	}
+
+	s, err = OutputWith(map[string]string{"MAGE_FOOBAR": "hi!"}, "echo", "$MAGE_FOOBAR")
+	if err != nil {
+		t.Fatal(err)
+	}
+	if s != "hi!" {
+		t.Fatalf(`Expected "hi!" but got %q`, s)
+	}
+}
diff --git a/sh/testmain_test.go b/sh/testmain_test.go
new file mode 100644
index 0000000..5869c54
--- /dev/null
+++ b/sh/testmain_test.go
@@ -0,0 +1,46 @@
+package sh
+
+import (
+	"flag"
+	"fmt"
+	"os"
+	"testing"
+)
+
+var (
+	helperCmd bool
+	printArgs bool
+	stderr    string
+	stdout    string
+	exitCode  int
+	printVar  string
+)
+
+func init() {
+	flag.BoolVar(&helperCmd, "helper", false, "")
+	flag.BoolVar(&printArgs, "printArgs", false, "")
+	flag.StringVar(&stderr, "stderr", "", "")
+	flag.StringVar(&stdout, "stdout", "", "")
+	flag.IntVar(&exitCode, "exit", 0, "")
+	flag.StringVar(&printVar, "printVar", "", "")
+}
+
+func TestMain(m *testing.M) {
+	flag.Parse()
+
+	if printArgs {
+		fmt.Println(flag.Args())
+		return
+	}
+	if printVar != "" {
+		fmt.Println(os.Getenv(printVar))
+		return
+	}
+
+	if helperCmd {
+		fmt.Fprintln(os.Stderr, stderr)
+		fmt.Fprintln(os.Stdout, stdout)
+		os.Exit(exitCode)
+	}
+	os.Exit(m.Run())
+}
diff --git a/vendor/github.com/google/go-cmp/cmp/compare_test.go b/vendor/github.com/google/go-cmp/cmp/compare_test.go
deleted file mode 100644
index 36a4ecf..0000000
--- a/vendor/github.com/google/go-cmp/cmp/compare_test.go
+++ /dev/null
@@ -1,1795 +0,0 @@
-// Copyright 2017, The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE.md file.
-
-package cmp_test
-
-import (
-	"bytes"
-	"crypto/md5"
-	"fmt"
-	"io"
-	"math"
-	"math/rand"
-	"reflect"
-	"regexp"
-	"sort"
-	"strings"
-	"sync"
-	"testing"
-	"time"
-
-	"github.com/google/go-cmp/cmp"
-	"github.com/google/go-cmp/cmp/cmpopts"
-	pb "github.com/google/go-cmp/cmp/internal/testprotos"
-	ts "github.com/google/go-cmp/cmp/internal/teststructs"
-)
-
-var now = time.Now()
-
-func intPtr(n int) *int { return &n }
-
-type test struct {
-	label     string       // Test description
-	x, y      interface{}  // Input values to compare
-	opts      []cmp.Option // Input options
-	wantDiff  string       // The exact difference string
-	wantPanic string       // Sub-string of an expected panic message
-}
-
-func TestDiff(t *testing.T) {
-	var tests []test
-	tests = append(tests, comparerTests()...)
-	tests = append(tests, transformerTests()...)
-	tests = append(tests, embeddedTests()...)
-	tests = append(tests, methodTests()...)
-	tests = append(tests, project1Tests()...)
-	tests = append(tests, project2Tests()...)
-	tests = append(tests, project3Tests()...)
-	tests = append(tests, project4Tests()...)
-
-	for _, tt := range tests {
-		tt := tt
-		tRunParallel(t, tt.label, func(t *testing.T) {
-			var gotDiff, gotPanic string
-			func() {
-				defer func() {
-					if ex := recover(); ex != nil {
-						if s, ok := ex.(string); ok {
-							gotPanic = s
-						} else {
-							panic(ex)
-						}
-					}
-				}()
-				gotDiff = cmp.Diff(tt.x, tt.y, tt.opts...)
-			}()
-			if tt.wantPanic == "" {
-				if gotPanic != "" {
-					t.Fatalf("unexpected panic message: %s", gotPanic)
-				}
-				if got, want := strings.TrimSpace(gotDiff), strings.TrimSpace(tt.wantDiff); got != want {
-					t.Fatalf("difference message:\ngot:\n%s\n\nwant:\n%s", got, want)
-				}
-			} else {
-				if !strings.Contains(gotPanic, tt.wantPanic) {
-					t.Fatalf("panic message:\ngot:  %s\nwant: %s", gotPanic, tt.wantPanic)
-				}
-			}
-		})
-	}
-}
-
-func comparerTests() []test {
-	const label = "Comparer"
-
-	return []test{{
-		label: label,
-		x:     1,
-		y:     1,
-	}, {
-		label:     label,
-		x:         1,
-		y:         1,
-		opts:      []cmp.Option{cmp.Ignore()},
-		wantPanic: "cannot use an unfiltered option",
-	}, {
-		label:     label,
-		x:         1,
-		y:         1,
-		opts:      []cmp.Option{cmp.Comparer(func(_, _ interface{}) bool { return true })},
-		wantPanic: "cannot use an unfiltered option",
-	}, {
-		label:     label,
-		x:         1,
-		y:         1,
-		opts:      []cmp.Option{cmp.Transformer("", func(x interface{}) interface{} { return x })},
-		wantPanic: "cannot use an unfiltered option",
-	}, {
-		label: label,
-		x:     1,
-		y:     1,
-		opts: []cmp.Option{
-			cmp.Comparer(func(x, y int) bool { return true }),
-			cmp.Transformer("", func(x int) float64 { return float64(x) }),
-		},
-		wantPanic: "ambiguous set of applicable options",
-	}, {
-		label: label,
-		x:     1,
-		y:     1,
-		opts: []cmp.Option{
-			cmp.FilterPath(func(p cmp.Path) bool {
-				return len(p) > 0 && p[len(p)-1].Type().Kind() == reflect.Int
-			}, cmp.Options{cmp.Ignore(), cmp.Ignore(), cmp.Ignore()}),
-			cmp.Comparer(func(x, y int) bool { return true }),
-			cmp.Transformer("", func(x int) float64 { return float64(x) }),
-		},
-	}, {
-		label:     label,
-		opts:      []cmp.Option{struct{ cmp.Option }{}},
-		wantPanic: "unknown option",
-	}, {
-		label: label,
-		x:     struct{ A, B, C int }{1, 2, 3},
-		y:     struct{ A, B, C int }{1, 2, 3},
-	}, {
-		label:    label,
-		x:        struct{ A, B, C int }{1, 2, 3},
-		y:        struct{ A, B, C int }{1, 2, 4},
-		wantDiff: "root.C:\n\t-: 3\n\t+: 4\n",
-	}, {
-		label:     label,
-		x:         struct{ a, b, c int }{1, 2, 3},
-		y:         struct{ a, b, c int }{1, 2, 4},
-		wantPanic: "cannot handle unexported field",
-	}, {
-		label: label,
-		x:     &struct{ A *int }{intPtr(4)},
-		y:     &struct{ A *int }{intPtr(4)},
-	}, {
-		label:    label,
-		x:        &struct{ A *int }{intPtr(4)},
-		y:        &struct{ A *int }{intPtr(5)},
-		wantDiff: "*root.A:\n\t-: 4\n\t+: 5\n",
-	}, {
-		label: label,
-		x:     &struct{ A *int }{intPtr(4)},
-		y:     &struct{ A *int }{intPtr(5)},
-		opts: []cmp.Option{
-			cmp.Comparer(func(x, y int) bool { return true }),
-		},
-	}, {
-		label: label,
-		x:     &struct{ A *int }{intPtr(4)},
-		y:     &struct{ A *int }{intPtr(5)},
-		opts: []cmp.Option{
-			cmp.Comparer(func(x, y *int) bool { return x != nil && y != nil }),
-		},
-	}, {
-		label: label,
-		x:     &struct{ R *bytes.Buffer }{},
-		y:     &struct{ R *bytes.Buffer }{},
-	}, {
-		label:    label,
-		x:        &struct{ R *bytes.Buffer }{new(bytes.Buffer)},
-		y:        &struct{ R *bytes.Buffer }{},
-		wantDiff: "root.R:\n\t-: \"\"\n\t+: <nil>\n",
-	}, {
-		label: label,
-		x:     &struct{ R *bytes.Buffer }{new(bytes.Buffer)},
-		y:     &struct{ R *bytes.Buffer }{},
-		opts: []cmp.Option{
-			cmp.Comparer(func(x, y io.Reader) bool { return true }),
-		},
-	}, {
-		label:     label,
-		x:         &struct{ R bytes.Buffer }{},
-		y:         &struct{ R bytes.Buffer }{},
-		wantPanic: "cannot handle unexported field",
-	}, {
-		label: label,
-		x:     &struct{ R bytes.Buffer }{},
-		y:     &struct{ R bytes.Buffer }{},
-		opts: []cmp.Option{
-			cmp.Comparer(func(x, y io.Reader) bool { return true }),
-		},
-		wantPanic: "cannot handle unexported field",
-	}, {
-		label: label,
-		x:     &struct{ R bytes.Buffer }{},
-		y:     &struct{ R bytes.Buffer }{},
-		opts: []cmp.Option{
-			cmp.Transformer("Ref", func(x bytes.Buffer) *bytes.Buffer { return &x }),
-			cmp.Comparer(func(x, y io.Reader) bool { return true }),
-		},
-	}, {
-		label:     label,
-		x:         []*regexp.Regexp{nil, regexp.MustCompile("a*b*c*")},
-		y:         []*regexp.Regexp{nil, regexp.MustCompile("a*b*c*")},
-		wantPanic: "cannot handle unexported field",
-	}, {
-		label: label,
-		x:     []*regexp.Regexp{nil, regexp.MustCompile("a*b*c*")},
-		y:     []*regexp.Regexp{nil, regexp.MustCompile("a*b*c*")},
-		opts: []cmp.Option{cmp.Comparer(func(x, y *regexp.Regexp) bool {
-			if x == nil || y == nil {
-				return x == nil && y == nil
-			}
-			return x.String() == y.String()
-		})},
-	}, {
-		label: label,
-		x:     []*regexp.Regexp{nil, regexp.MustCompile("a*b*c*")},
-		y:     []*regexp.Regexp{nil, regexp.MustCompile("a*b*d*")},
-		opts: []cmp.Option{cmp.Comparer(func(x, y *regexp.Regexp) bool {
-			if x == nil || y == nil {
-				return x == nil && y == nil
-			}
-			return x.String() == y.String()
-		})},
-		wantDiff: `
-{[]*regexp.Regexp}[1]:
-	-: "a*b*c*"
-	+: "a*b*d*"`,
-	}, {
-		label: label,
-		x: func() ***int {
-			a := 0
-			b := &a
-			c := &b
-			return &c
-		}(),
-		y: func() ***int {
-			a := 0
-			b := &a
-			c := &b
-			return &c
-		}(),
-	}, {
-		label: label,
-		x: func() ***int {
-			a := 0
-			b := &a
-			c := &b
-			return &c
-		}(),
-		y: func() ***int {
-			a := 1
-			b := &a
-			c := &b
-			return &c
-		}(),
-		wantDiff: `
-***{***int}:
-	-: 0
-	+: 1`,
-	}, {
-		label: label,
-		x:     []int{1, 2, 3, 4, 5}[:3],
-		y:     []int{1, 2, 3},
-	}, {
-		label: label,
-		x:     struct{ fmt.Stringer }{bytes.NewBufferString("hello")},
-		y:     struct{ fmt.Stringer }{regexp.MustCompile("hello")},
-		opts:  []cmp.Option{cmp.Comparer(func(x, y fmt.Stringer) bool { return x.String() == y.String() })},
-	}, {
-		label: label,
-		x:     struct{ fmt.Stringer }{bytes.NewBufferString("hello")},
-		y:     struct{ fmt.Stringer }{regexp.MustCompile("hello2")},
-		opts:  []cmp.Option{cmp.Comparer(func(x, y fmt.Stringer) bool { return x.String() == y.String() })},
-		wantDiff: `
-root:
-	-: "hello"
-	+: "hello2"`,
-	}, {
-		label: label,
-		x:     md5.Sum([]byte{'a'}),
-		y:     md5.Sum([]byte{'b'}),
-		wantDiff: `
-{[16]uint8}:
-	-: [16]uint8{0x0c, 0xc1, 0x75, 0xb9, 0xc0, 0xf1, 0xb6, 0xa8, 0x31, 0xc3, 0x99, 0xe2, 0x69, 0x77, 0x26, 0x61}
-	+: [16]uint8{0x92, 0xeb, 0x5f, 0xfe, 0xe6, 0xae, 0x2f, 0xec, 0x3a, 0xd7, 0x1c, 0x77, 0x75, 0x31, 0x57, 0x8f}`,
-	}, {
-		label: label,
-		x:     new(fmt.Stringer),
-		y:     nil,
-		wantDiff: `
-:
-	-: &<nil>
-	+: <non-existent>`,
-	}, {
-		label: label,
-		x:     make([]int, 1000),
-		y:     make([]int, 1000),
-		opts: []cmp.Option{
-			cmp.Comparer(func(_, _ int) bool {
-				return rand.Intn(2) == 0
-			}),
-		},
-		wantPanic: "non-deterministic or non-symmetric function detected",
-	}, {
-		label: label,
-		x:     make([]int, 1000),
-		y:     make([]int, 1000),
-		opts: []cmp.Option{
-			cmp.FilterValues(func(_, _ int) bool {
-				return rand.Intn(2) == 0
-			}, cmp.Ignore()),
-		},
-		wantPanic: "non-deterministic or non-symmetric function detected",
-	}, {
-		label: label,
-		x:     []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10},
-		y:     []int{10, 9, 8, 7, 6, 5, 4, 3, 2, 1},
-		opts: []cmp.Option{
-			cmp.Comparer(func(x, y int) bool {
-				return x < y
-			}),
-		},
-		wantPanic: "non-deterministic or non-symmetric function detected",
-	}, {
-		label: label,
-		x:     make([]string, 1000),
-		y:     make([]string, 1000),
-		opts: []cmp.Option{
-			cmp.Transformer("", func(x string) int {
-				return rand.Int()
-			}),
-		},
-		wantPanic: "non-deterministic function detected",
-	}, {
-		// Make sure the dynamic checks don't raise a false positive for
-		// non-reflexive comparisons.
-		label: label,
-		x:     make([]int, 10),
-		y:     make([]int, 10),
-		opts: []cmp.Option{
-			cmp.Transformer("", func(x int) float64 {
-				return math.NaN()
-			}),
-		},
-		wantDiff: `
-{[]int}:
-	-: []int{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
-	+: []int{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}`,
-	}}
-}
-
-func transformerTests() []test {
-	const label = "Transformer/"
-
-	return []test{{
-		label: label,
-		x:     uint8(0),
-		y:     uint8(1),
-		opts: []cmp.Option{
-			cmp.Transformer("", func(in uint8) uint16 { return uint16(in) }),
-			cmp.Transformer("", func(in uint16) uint32 { return uint32(in) }),
-			cmp.Transformer("", func(in uint32) uint64 { return uint64(in) }),
-		},
-		wantDiff: `
-λ(λ(λ({uint8}))):
-	-: 0x00
-	+: 0x01`,
-	}, {
-		label: label,
-		x:     0,
-		y:     1,
-		opts: []cmp.Option{
-			cmp.Transformer("", func(in int) int { return in / 2 }),
-			cmp.Transformer("", func(in int) int { return in }),
-		},
-		wantPanic: "ambiguous set of applicable options",
-	}, {
-		label: label,
-		x:     []int{0, -5, 0, -1},
-		y:     []int{1, 3, 0, -5},
-		opts: []cmp.Option{
-			cmp.FilterValues(
-				func(x, y int) bool { return x+y >= 0 },
-				cmp.Transformer("", func(in int) int64 { return int64(in / 2) }),
-			),
-			cmp.FilterValues(
-				func(x, y int) bool { return x+y < 0 },
-				cmp.Transformer("", func(in int) int64 { return int64(in) }),
-			),
-		},
-		wantDiff: `
-λ({[]int}[1]):
-	-: -5
-	+: 3
-λ({[]int}[3]):
-	-: -1
-	+: -5`,
-	}, {
-		label: label,
-		x:     0,
-		y:     1,
-		opts: []cmp.Option{
-			cmp.Transformer("", func(in int) interface{} {
-				if in == 0 {
-					return "string"
-				}
-				return float64(in)
-			}),
-		},
-		wantDiff: `
-λ({int}):
-	-: "string"
-	+: 1`,
-	}}
-}
-
-func embeddedTests() []test {
-	const label = "EmbeddedStruct/"
-
-	privateStruct := *new(ts.ParentStructA).PrivateStruct()
-
-	createStructA := func(i int) ts.ParentStructA {
-		s := ts.ParentStructA{}
-		s.PrivateStruct().Public = 1 + i
-		s.PrivateStruct().SetPrivate(2 + i)
-		return s
-	}
-
-	createStructB := func(i int) ts.ParentStructB {
-		s := ts.ParentStructB{}
-		s.PublicStruct.Public = 1 + i
-		s.PublicStruct.SetPrivate(2 + i)
-		return s
-	}
-
-	createStructC := func(i int) ts.ParentStructC {
-		s := ts.ParentStructC{}
-		s.PrivateStruct().Public = 1 + i
-		s.PrivateStruct().SetPrivate(2 + i)
-		s.Public = 3 + i
-		s.SetPrivate(4 + i)
-		return s
-	}
-
-	createStructD := func(i int) ts.ParentStructD {
-		s := ts.ParentStructD{}
-		s.PublicStruct.Public = 1 + i
-		s.PublicStruct.SetPrivate(2 + i)
-		s.Public = 3 + i
-		s.SetPrivate(4 + i)
-		return s
-	}
-
-	createStructE := func(i int) ts.ParentStructE {
-		s := ts.ParentStructE{}
-		s.PrivateStruct().Public = 1 + i
-		s.PrivateStruct().SetPrivate(2 + i)
-		s.PublicStruct.Public = 3 + i
-		s.PublicStruct.SetPrivate(4 + i)
-		return s
-	}
-
-	createStructF := func(i int) ts.ParentStructF {
-		s := ts.ParentStructF{}
-		s.PrivateStruct().Public = 1 + i
-		s.PrivateStruct().SetPrivate(2 + i)
-		s.PublicStruct.Public = 3 + i
-		s.PublicStruct.SetPrivate(4 + i)
-		s.Public = 5 + i
-		s.SetPrivate(6 + i)
-		return s
-	}
-
-	createStructG := func(i int) *ts.ParentStructG {
-		s := ts.NewParentStructG()
-		s.PrivateStruct().Public = 1 + i
-		s.PrivateStruct().SetPrivate(2 + i)
-		return s
-	}
-
-	createStructH := func(i int) *ts.ParentStructH {
-		s := ts.NewParentStructH()
-		s.PublicStruct.Public = 1 + i
-		s.PublicStruct.SetPrivate(2 + i)
-		return s
-	}
-
-	createStructI := func(i int) *ts.ParentStructI {
-		s := ts.NewParentStructI()
-		s.PrivateStruct().Public = 1 + i
-		s.PrivateStruct().SetPrivate(2 + i)
-		s.PublicStruct.Public = 3 + i
-		s.PublicStruct.SetPrivate(4 + i)
-		return s
-	}
-
-	createStructJ := func(i int) *ts.ParentStructJ {
-		s := ts.NewParentStructJ()
-		s.PrivateStruct().Public = 1 + i
-		s.PrivateStruct().SetPrivate(2 + i)
-		s.PublicStruct.Public = 3 + i
-		s.PublicStruct.SetPrivate(4 + i)
-		s.Private().Public = 5 + i
-		s.Private().SetPrivate(6 + i)
-		s.Public.Public = 7 + i
-		s.Public.SetPrivate(8 + i)
-		return s
-	}
-
-	return []test{{
-		label:     label + "ParentStructA",
-		x:         ts.ParentStructA{},
-		y:         ts.ParentStructA{},
-		wantPanic: "cannot handle unexported field",
-	}, {
-		label: label + "ParentStructA",
-		x:     ts.ParentStructA{},
-		y:     ts.ParentStructA{},
-		opts: []cmp.Option{
-			cmpopts.IgnoreUnexported(ts.ParentStructA{}),
-		},
-	}, {
-		label: label + "ParentStructA",
-		x:     createStructA(0),
-		y:     createStructA(0),
-		opts: []cmp.Option{
-			cmp.AllowUnexported(ts.ParentStructA{}),
-		},
-		wantPanic: "cannot handle unexported field",
-	}, {
-		label: label + "ParentStructA",
-		x:     createStructA(0),
-		y:     createStructA(0),
-		opts: []cmp.Option{
-			cmp.AllowUnexported(ts.ParentStructA{}, privateStruct),
-		},
-	}, {
-		label: label + "ParentStructA",
-		x:     createStructA(0),
-		y:     createStructA(1),
-		opts: []cmp.Option{
-			cmp.AllowUnexported(ts.ParentStructA{}, privateStruct),
-		},
-		wantDiff: `
-{teststructs.ParentStructA}.privateStruct.Public:
-	-: 1
-	+: 2
-{teststructs.ParentStructA}.privateStruct.private:
-	-: 2
-	+: 3`,
-	}, {
-		label: label + "ParentStructB",
-		x:     ts.ParentStructB{},
-		y:     ts.ParentStructB{},
-		opts: []cmp.Option{
-			cmpopts.IgnoreUnexported(ts.ParentStructB{}),
-		},
-		wantPanic: "cannot handle unexported field",
-	}, {
-		label: label + "ParentStructB",
-		x:     ts.ParentStructB{},
-		y:     ts.ParentStructB{},
-		opts: []cmp.Option{
-			cmpopts.IgnoreUnexported(ts.ParentStructB{}),
-			cmpopts.IgnoreUnexported(ts.PublicStruct{}),
-		},
-	}, {
-		label: label + "ParentStructB",
-		x:     createStructB(0),
-		y:     createStructB(0),
-		opts: []cmp.Option{
-			cmp.AllowUnexported(ts.ParentStructB{}),
-		},
-		wantPanic: "cannot handle unexported field",
-	}, {
-		label: label + "ParentStructB",
-		x:     createStructB(0),
-		y:     createStructB(0),
-		opts: []cmp.Option{
-			cmp.AllowUnexported(ts.ParentStructB{}, ts.PublicStruct{}),
-		},
-	}, {
-		label: label + "ParentStructB",
-		x:     createStructB(0),
-		y:     createStructB(1),
-		opts: []cmp.Option{
-			cmp.AllowUnexported(ts.ParentStructB{}, ts.PublicStruct{}),
-		},
-		wantDiff: `
-{teststructs.ParentStructB}.PublicStruct.Public:
-	-: 1
-	+: 2
-{teststructs.ParentStructB}.PublicStruct.private:
-	-: 2
-	+: 3`,
-	}, {
-		label:     label + "ParentStructC",
-		x:         ts.ParentStructC{},
-		y:         ts.ParentStructC{},
-		wantPanic: "cannot handle unexported field",
-	}, {
-		label: label + "ParentStructC",
-		x:     ts.ParentStructC{},
-		y:     ts.ParentStructC{},
-		opts: []cmp.Option{
-			cmpopts.IgnoreUnexported(ts.ParentStructC{}),
-		},
-	}, {
-		label: label + "ParentStructC",
-		x:     createStructC(0),
-		y:     createStructC(0),
-		opts: []cmp.Option{
-			cmp.AllowUnexported(ts.ParentStructC{}),
-		},
-		wantPanic: "cannot handle unexported field",
-	}, {
-		label: label + "ParentStructC",
-		x:     createStructC(0),
-		y:     createStructC(0),
-		opts: []cmp.Option{
-			cmp.AllowUnexported(ts.ParentStructC{}, privateStruct),
-		},
-	}, {
-		label: label + "ParentStructC",
-		x:     createStructC(0),
-		y:     createStructC(1),
-		opts: []cmp.Option{
-			cmp.AllowUnexported(ts.ParentStructC{}, privateStruct),
-		},
-		wantDiff: `
-{teststructs.ParentStructC}.privateStruct.Public:
-	-: 1
-	+: 2
-{teststructs.ParentStructC}.privateStruct.private:
-	-: 2
-	+: 3
-{teststructs.ParentStructC}.Public:
-	-: 3
-	+: 4
-{teststructs.ParentStructC}.private:
-	-: 4
-	+: 5`,
-	}, {
-		label: label + "ParentStructD",
-		x:     ts.ParentStructD{},
-		y:     ts.ParentStructD{},
-		opts: []cmp.Option{
-			cmpopts.IgnoreUnexported(ts.ParentStructD{}),
-		},
-		wantPanic: "cannot handle unexported field",
-	}, {
-		label: label + "ParentStructD",
-		x:     ts.ParentStructD{},
-		y:     ts.ParentStructD{},
-		opts: []cmp.Option{
-			cmpopts.IgnoreUnexported(ts.ParentStructD{}),
-			cmpopts.IgnoreUnexported(ts.PublicStruct{}),
-		},
-	}, {
-		label: label + "ParentStructD",
-		x:     createStructD(0),
-		y:     createStructD(0),
-		opts: []cmp.Option{
-			cmp.AllowUnexported(ts.ParentStructD{}),
-		},
-		wantPanic: "cannot handle unexported field",
-	}, {
-		label: label + "ParentStructD",
-		x:     createStructD(0),
-		y:     createStructD(0),
-		opts: []cmp.Option{
-			cmp.AllowUnexported(ts.ParentStructD{}, ts.PublicStruct{}),
-		},
-	}, {
-		label: label + "ParentStructD",
-		x:     createStructD(0),
-		y:     createStructD(1),
-		opts: []cmp.Option{
-			cmp.AllowUnexported(ts.ParentStructD{}, ts.PublicStruct{}),
-		},
-		wantDiff: `
-{teststructs.ParentStructD}.PublicStruct.Public:
-	-: 1
-	+: 2
-{teststructs.ParentStructD}.PublicStruct.private:
-	-: 2
-	+: 3
-{teststructs.ParentStructD}.Public:
-	-: 3
-	+: 4
-{teststructs.ParentStructD}.private:
-	-: 4
-	+: 5`,
-	}, {
-		label: label + "ParentStructE",
-		x:     ts.ParentStructE{},
-		y:     ts.ParentStructE{},
-		opts: []cmp.Option{
-			cmpopts.IgnoreUnexported(ts.ParentStructE{}),
-		},
-		wantPanic: "cannot handle unexported field",
-	}, {
-		label: label + "ParentStructE",
-		x:     ts.ParentStructE{},
-		y:     ts.ParentStructE{},
-		opts: []cmp.Option{
-			cmpopts.IgnoreUnexported(ts.ParentStructE{}),
-			cmpopts.IgnoreUnexported(ts.PublicStruct{}),
-		},
-	}, {
-		label: label + "ParentStructE",
-		x:     createStructE(0),
-		y:     createStructE(0),
-		opts: []cmp.Option{
-			cmp.AllowUnexported(ts.ParentStructE{}),
-		},
-		wantPanic: "cannot handle unexported field",
-	}, {
-		label: label + "ParentStructE",
-		x:     createStructE(0),
-		y:     createStructE(0),
-		opts: []cmp.Option{
-			cmp.AllowUnexported(ts.ParentStructE{}, ts.PublicStruct{}),
-		},
-		wantPanic: "cannot handle unexported field",
-	}, {
-		label: label + "ParentStructE",
-		x:     createStructE(0),
-		y:     createStructE(0),
-		opts: []cmp.Option{
-			cmp.AllowUnexported(ts.ParentStructE{}, ts.PublicStruct{}, privateStruct),
-		},
-	}, {
-		label: label + "ParentStructE",
-		x:     createStructE(0),
-		y:     createStructE(1),
-		opts: []cmp.Option{
-			cmp.AllowUnexported(ts.ParentStructE{}, ts.PublicStruct{}, privateStruct),
-		},
-		wantDiff: `
-{teststructs.ParentStructE}.privateStruct.Public:
-	-: 1
-	+: 2
-{teststructs.ParentStructE}.privateStruct.private:
-	-: 2
-	+: 3
-{teststructs.ParentStructE}.PublicStruct.Public:
-	-: 3
-	+: 4
-{teststructs.ParentStructE}.PublicStruct.private:
-	-: 4
-	+: 5`,
-	}, {
-		label: label + "ParentStructF",
-		x:     ts.ParentStructF{},
-		y:     ts.ParentStructF{},
-		opts: []cmp.Option{
-			cmpopts.IgnoreUnexported(ts.ParentStructF{}),
-		},
-		wantPanic: "cannot handle unexported field",
-	}, {
-		label: label + "ParentStructF",
-		x:     ts.ParentStructF{},
-		y:     ts.ParentStructF{},
-		opts: []cmp.Option{
-			cmpopts.IgnoreUnexported(ts.ParentStructF{}),
-			cmpopts.IgnoreUnexported(ts.PublicStruct{}),
-		},
-	}, {
-		label: label + "ParentStructF",
-		x:     createStructF(0),
-		y:     createStructF(0),
-		opts: []cmp.Option{
-			cmp.AllowUnexported(ts.ParentStructF{}),
-		},
-		wantPanic: "cannot handle unexported field",
-	}, {
-		label: label + "ParentStructF",
-		x:     createStructF(0),
-		y:     createStructF(0),
-		opts: []cmp.Option{
-			cmp.AllowUnexported(ts.ParentStructF{}, ts.PublicStruct{}),
-		},
-		wantPanic: "cannot handle unexported field",
-	}, {
-		label: label + "ParentStructF",
-		x:     createStructF(0),
-		y:     createStructF(0),
-		opts: []cmp.Option{
-			cmp.AllowUnexported(ts.ParentStructF{}, ts.PublicStruct{}, privateStruct),
-		},
-	}, {
-		label: label + "ParentStructF",
-		x:     createStructF(0),
-		y:     createStructF(1),
-		opts: []cmp.Option{
-			cmp.AllowUnexported(ts.ParentStructF{}, ts.PublicStruct{}, privateStruct),
-		},
-		wantDiff: `
-{teststructs.ParentStructF}.privateStruct.Public:
-	-: 1
-	+: 2
-{teststructs.ParentStructF}.privateStruct.private:
-	-: 2
-	+: 3
-{teststructs.ParentStructF}.PublicStruct.Public:
-	-: 3
-	+: 4
-{teststructs.ParentStructF}.PublicStruct.private:
-	-: 4
-	+: 5
-{teststructs.ParentStructF}.Public:
-	-: 5
-	+: 6
-{teststructs.ParentStructF}.private:
-	-: 6
-	+: 7`,
-	}, {
-		label:     label + "ParentStructG",
-		x:         ts.ParentStructG{},
-		y:         ts.ParentStructG{},
-		wantPanic: "cannot handle unexported field",
-	}, {
-		label: label + "ParentStructG",
-		x:     ts.ParentStructG{},
-		y:     ts.ParentStructG{},
-		opts: []cmp.Option{
-			cmpopts.IgnoreUnexported(ts.ParentStructG{}),
-		},
-	}, {
-		label: label + "ParentStructG",
-		x:     createStructG(0),
-		y:     createStructG(0),
-		opts: []cmp.Option{
-			cmp.AllowUnexported(ts.ParentStructG{}),
-		},
-		wantPanic: "cannot handle unexported field",
-	}, {
-		label: label + "ParentStructG",
-		x:     createStructG(0),
-		y:     createStructG(0),
-		opts: []cmp.Option{
-			cmp.AllowUnexported(ts.ParentStructG{}, privateStruct),
-		},
-	}, {
-		label: label + "ParentStructG",
-		x:     createStructG(0),
-		y:     createStructG(1),
-		opts: []cmp.Option{
-			cmp.AllowUnexported(ts.ParentStructG{}, privateStruct),
-		},
-		wantDiff: `
-{*teststructs.ParentStructG}.privateStruct.Public:
-	-: 1
-	+: 2
-{*teststructs.ParentStructG}.privateStruct.private:
-	-: 2
-	+: 3`,
-	}, {
-		label: label + "ParentStructH",
-		x:     ts.ParentStructH{},
-		y:     ts.ParentStructH{},
-	}, {
-		label:     label + "ParentStructH",
-		x:         createStructH(0),
-		y:         createStructH(0),
-		wantPanic: "cannot handle unexported field",
-	}, {
-		label: label + "ParentStructH",
-		x:     ts.ParentStructH{},
-		y:     ts.ParentStructH{},
-		opts: []cmp.Option{
-			cmpopts.IgnoreUnexported(ts.ParentStructH{}),
-		},
-	}, {
-		label: label + "ParentStructH",
-		x:     createStructH(0),
-		y:     createStructH(0),
-		opts: []cmp.Option{
-			cmp.AllowUnexported(ts.ParentStructH{}),
-		},
-		wantPanic: "cannot handle unexported field",
-	}, {
-		label: label + "ParentStructH",
-		x:     createStructH(0),
-		y:     createStructH(0),
-		opts: []cmp.Option{
-			cmp.AllowUnexported(ts.ParentStructH{}, ts.PublicStruct{}),
-		},
-	}, {
-		label: label + "ParentStructH",
-		x:     createStructH(0),
-		y:     createStructH(1),
-		opts: []cmp.Option{
-			cmp.AllowUnexported(ts.ParentStructH{}, ts.PublicStruct{}),
-		},
-		wantDiff: `
-{*teststructs.ParentStructH}.PublicStruct.Public:
-	-: 1
-	+: 2
-{*teststructs.ParentStructH}.PublicStruct.private:
-	-: 2
-	+: 3`,
-	}, {
-		label:     label + "ParentStructI",
-		x:         ts.ParentStructI{},
-		y:         ts.ParentStructI{},
-		wantPanic: "cannot handle unexported field",
-	}, {
-		label: label + "ParentStructI",
-		x:     ts.ParentStructI{},
-		y:     ts.ParentStructI{},
-		opts: []cmp.Option{
-			cmpopts.IgnoreUnexported(ts.ParentStructI{}),
-		},
-	}, {
-		label: label + "ParentStructI",
-		x:     createStructI(0),
-		y:     createStructI(0),
-		opts: []cmp.Option{
-			cmpopts.IgnoreUnexported(ts.ParentStructI{}),
-		},
-		wantPanic: "cannot handle unexported field",
-	}, {
-		label: label + "ParentStructI",
-		x:     createStructI(0),
-		y:     createStructI(0),
-		opts: []cmp.Option{
-			cmpopts.IgnoreUnexported(ts.ParentStructI{}, ts.PublicStruct{}),
-		},
-	}, {
-		label: label + "ParentStructI",
-		x:     createStructI(0),
-		y:     createStructI(0),
-		opts: []cmp.Option{
-			cmp.AllowUnexported(ts.ParentStructI{}),
-		},
-		wantPanic: "cannot handle unexported field",
-	}, {
-		label: label + "ParentStructI",
-		x:     createStructI(0),
-		y:     createStructI(0),
-		opts: []cmp.Option{
-			cmp.AllowUnexported(ts.ParentStructI{}, ts.PublicStruct{}, privateStruct),
-		},
-	}, {
-		label: label + "ParentStructI",
-		x:     createStructI(0),
-		y:     createStructI(1),
-		opts: []cmp.Option{
-			cmp.AllowUnexported(ts.ParentStructI{}, ts.PublicStruct{}, privateStruct),
-		},
-		wantDiff: `
-{*teststructs.ParentStructI}.privateStruct.Public:
-	-: 1
-	+: 2
-{*teststructs.ParentStructI}.privateStruct.private:
-	-: 2
-	+: 3
-{*teststructs.ParentStructI}.PublicStruct.Public:
-	-: 3
-	+: 4
-{*teststructs.ParentStructI}.PublicStruct.private:
-	-: 4
-	+: 5`,
-	}, {
-		label:     label + "ParentStructJ",
-		x:         ts.ParentStructJ{},
-		y:         ts.ParentStructJ{},
-		wantPanic: "cannot handle unexported field",
-	}, {
-		label: label + "ParentStructJ",
-		x:     ts.ParentStructJ{},
-		y:     ts.ParentStructJ{},
-		opts: []cmp.Option{
-			cmpopts.IgnoreUnexported(ts.ParentStructJ{}),
-		},
-		wantPanic: "cannot handle unexported field",
-	}, {
-		label: label + "ParentStructJ",
-		x:     ts.ParentStructJ{},
-		y:     ts.ParentStructJ{},
-		opts: []cmp.Option{
-			cmpopts.IgnoreUnexported(ts.ParentStructJ{}, ts.PublicStruct{}),
-		},
-	}, {
-		label: label + "ParentStructJ",
-		x:     createStructJ(0),
-		y:     createStructJ(0),
-		opts: []cmp.Option{
-			cmp.AllowUnexported(ts.ParentStructJ{}, ts.PublicStruct{}),
-		},
-		wantPanic: "cannot handle unexported field",
-	}, {
-		label: label + "ParentStructJ",
-		x:     createStructJ(0),
-		y:     createStructJ(0),
-		opts: []cmp.Option{
-			cmp.AllowUnexported(ts.ParentStructJ{}, ts.PublicStruct{}, privateStruct),
-		},
-	}, {
-		label: label + "ParentStructJ",
-		x:     createStructJ(0),
-		y:     createStructJ(1),
-		opts: []cmp.Option{
-			cmp.AllowUnexported(ts.ParentStructJ{}, ts.PublicStruct{}, privateStruct),
-		},
-		wantDiff: `
-{*teststructs.ParentStructJ}.privateStruct.Public:
-	-: 1
-	+: 2
-{*teststructs.ParentStructJ}.privateStruct.private:
-	-: 2
-	+: 3
-{*teststructs.ParentStructJ}.PublicStruct.Public:
-	-: 3
-	+: 4
-{*teststructs.ParentStructJ}.PublicStruct.private:
-	-: 4
-	+: 5
-{*teststructs.ParentStructJ}.Public.Public:
-	-: 7
-	+: 8
-{*teststructs.ParentStructJ}.Public.private:
-	-: 8
-	+: 9
-{*teststructs.ParentStructJ}.private.Public:
-	-: 5
-	+: 6
-{*teststructs.ParentStructJ}.private.private:
-	-: 6
-	+: 7`,
-	}}
-}
-
-func methodTests() []test {
-	const label = "EqualMethod/"
-
-	// A common mistake that the Equal method is on a pointer receiver,
-	// but only a non-pointer value is present in the struct.
-	// A transform can be used to forcibly reference the value.
-	derefTransform := cmp.FilterPath(func(p cmp.Path) bool {
-		if len(p) == 0 {
-			return false
-		}
-		t := p[len(p)-1].Type()
-		if _, ok := t.MethodByName("Equal"); ok || t.Kind() == reflect.Ptr {
-			return false
-		}
-		if m, ok := reflect.PtrTo(t).MethodByName("Equal"); ok {
-			tf := m.Func.Type()
-			return !tf.IsVariadic() && tf.NumIn() == 2 && tf.NumOut() == 1 &&
-				tf.In(0).AssignableTo(tf.In(1)) && tf.Out(0) == reflect.TypeOf(true)
-		}
-		return false
-	}, cmp.Transformer("Ref", func(x interface{}) interface{} {
-		v := reflect.ValueOf(x)
-		vp := reflect.New(v.Type())
-		vp.Elem().Set(v)
-		return vp.Interface()
-	}))
-
-	// For each of these types, there is an Equal method defined, which always
-	// returns true, while the underlying data are fundamentally different.
-	// Since the method should be called, these are expected to be equal.
-	return []test{{
-		label: label + "StructA",
-		x:     ts.StructA{"NotEqual"},
-		y:     ts.StructA{"not_equal"},
-	}, {
-		label: label + "StructA",
-		x:     &ts.StructA{"NotEqual"},
-		y:     &ts.StructA{"not_equal"},
-	}, {
-		label: label + "StructB",
-		x:     ts.StructB{"NotEqual"},
-		y:     ts.StructB{"not_equal"},
-		wantDiff: `
-{teststructs.StructB}.X:
-	-: "NotEqual"
-	+: "not_equal"`,
-	}, {
-		label: label + "StructB",
-		x:     ts.StructB{"NotEqual"},
-		y:     ts.StructB{"not_equal"},
-		opts:  []cmp.Option{derefTransform},
-	}, {
-		label: label + "StructB",
-		x:     &ts.StructB{"NotEqual"},
-		y:     &ts.StructB{"not_equal"},
-	}, {
-		label: label + "StructC",
-		x:     ts.StructC{"NotEqual"},
-		y:     ts.StructC{"not_equal"},
-	}, {
-		label: label + "StructC",
-		x:     &ts.StructC{"NotEqual"},
-		y:     &ts.StructC{"not_equal"},
-	}, {
-		label: label + "StructD",
-		x:     ts.StructD{"NotEqual"},
-		y:     ts.StructD{"not_equal"},
-		wantDiff: `
-{teststructs.StructD}.X:
-	-: "NotEqual"
-	+: "not_equal"`,
-	}, {
-		label: label + "StructD",
-		x:     ts.StructD{"NotEqual"},
-		y:     ts.StructD{"not_equal"},
-		opts:  []cmp.Option{derefTransform},
-	}, {
-		label: label + "StructD",
-		x:     &ts.StructD{"NotEqual"},
-		y:     &ts.StructD{"not_equal"},
-	}, {
-		label: label + "StructE",
-		x:     ts.StructE{"NotEqual"},
-		y:     ts.StructE{"not_equal"},
-		wantDiff: `
-{teststructs.StructE}.X:
-	-: "NotEqual"
-	+: "not_equal"`,
-	}, {
-		label: label + "StructE",
-		x:     ts.StructE{"NotEqual"},
-		y:     ts.StructE{"not_equal"},
-		opts:  []cmp.Option{derefTransform},
-	}, {
-		label: label + "StructE",
-		x:     &ts.StructE{"NotEqual"},
-		y:     &ts.StructE{"not_equal"},
-	}, {
-		label: label + "StructF",
-		x:     ts.StructF{"NotEqual"},
-		y:     ts.StructF{"not_equal"},
-		wantDiff: `
-{teststructs.StructF}.X:
-	-: "NotEqual"
-	+: "not_equal"`,
-	}, {
-		label: label + "StructF",
-		x:     &ts.StructF{"NotEqual"},
-		y:     &ts.StructF{"not_equal"},
-	}, {
-		label: label + "StructA1",
-		x:     ts.StructA1{ts.StructA{"NotEqual"}, "equal"},
-		y:     ts.StructA1{ts.StructA{"not_equal"}, "equal"},
-	}, {
-		label:    label + "StructA1",
-		x:        ts.StructA1{ts.StructA{"NotEqual"}, "NotEqual"},
-		y:        ts.StructA1{ts.StructA{"not_equal"}, "not_equal"},
-		wantDiff: "{teststructs.StructA1}.X:\n\t-: \"NotEqual\"\n\t+: \"not_equal\"\n",
-	}, {
-		label: label + "StructA1",
-		x:     &ts.StructA1{ts.StructA{"NotEqual"}, "equal"},
-		y:     &ts.StructA1{ts.StructA{"not_equal"}, "equal"},
-	}, {
-		label:    label + "StructA1",
-		x:        &ts.StructA1{ts.StructA{"NotEqual"}, "NotEqual"},
-		y:        &ts.StructA1{ts.StructA{"not_equal"}, "not_equal"},
-		wantDiff: "{*teststructs.StructA1}.X:\n\t-: \"NotEqual\"\n\t+: \"not_equal\"\n",
-	}, {
-		label: label + "StructB1",
-		x:     ts.StructB1{ts.StructB{"NotEqual"}, "equal"},
-		y:     ts.StructB1{ts.StructB{"not_equal"}, "equal"},
-		opts:  []cmp.Option{derefTransform},
-	}, {
-		label:    label + "StructB1",
-		x:        ts.StructB1{ts.StructB{"NotEqual"}, "NotEqual"},
-		y:        ts.StructB1{ts.StructB{"not_equal"}, "not_equal"},
-		opts:     []cmp.Option{derefTransform},
-		wantDiff: "{teststructs.StructB1}.X:\n\t-: \"NotEqual\"\n\t+: \"not_equal\"\n",
-	}, {
-		label: label + "StructB1",
-		x:     &ts.StructB1{ts.StructB{"NotEqual"}, "equal"},
-		y:     &ts.StructB1{ts.StructB{"not_equal"}, "equal"},
-		opts:  []cmp.Option{derefTransform},
-	}, {
-		label:    label + "StructB1",
-		x:        &ts.StructB1{ts.StructB{"NotEqual"}, "NotEqual"},
-		y:        &ts.StructB1{ts.StructB{"not_equal"}, "not_equal"},
-		opts:     []cmp.Option{derefTransform},
-		wantDiff: "{*teststructs.StructB1}.X:\n\t-: \"NotEqual\"\n\t+: \"not_equal\"\n",
-	}, {
-		label: label + "StructC1",
-		x:     ts.StructC1{ts.StructC{"NotEqual"}, "NotEqual"},
-		y:     ts.StructC1{ts.StructC{"not_equal"}, "not_equal"},
-	}, {
-		label: label + "StructC1",
-		x:     &ts.StructC1{ts.StructC{"NotEqual"}, "NotEqual"},
-		y:     &ts.StructC1{ts.StructC{"not_equal"}, "not_equal"},
-	}, {
-		label: label + "StructD1",
-		x:     ts.StructD1{ts.StructD{"NotEqual"}, "NotEqual"},
-		y:     ts.StructD1{ts.StructD{"not_equal"}, "not_equal"},
-		wantDiff: `
-{teststructs.StructD1}.StructD.X:
-	-: "NotEqual"
-	+: "not_equal"
-{teststructs.StructD1}.X:
-	-: "NotEqual"
-	+: "not_equal"`,
-	}, {
-		label: label + "StructD1",
-		x:     ts.StructD1{ts.StructD{"NotEqual"}, "NotEqual"},
-		y:     ts.StructD1{ts.StructD{"not_equal"}, "not_equal"},
-		opts:  []cmp.Option{derefTransform},
-	}, {
-		label: label + "StructD1",
-		x:     &ts.StructD1{ts.StructD{"NotEqual"}, "NotEqual"},
-		y:     &ts.StructD1{ts.StructD{"not_equal"}, "not_equal"},
-	}, {
-		label: label + "StructE1",
-		x:     ts.StructE1{ts.StructE{"NotEqual"}, "NotEqual"},
-		y:     ts.StructE1{ts.StructE{"not_equal"}, "not_equal"},
-		wantDiff: `
-{teststructs.StructE1}.StructE.X:
-	-: "NotEqual"
-	+: "not_equal"
-{teststructs.StructE1}.X:
-	-: "NotEqual"
-	+: "not_equal"`,
-	}, {
-		label: label + "StructE1",
-		x:     ts.StructE1{ts.StructE{"NotEqual"}, "NotEqual"},
-		y:     ts.StructE1{ts.StructE{"not_equal"}, "not_equal"},
-		opts:  []cmp.Option{derefTransform},
-	}, {
-		label: label + "StructE1",
-		x:     &ts.StructE1{ts.StructE{"NotEqual"}, "NotEqual"},
-		y:     &ts.StructE1{ts.StructE{"not_equal"}, "not_equal"},
-	}, {
-		label: label + "StructF1",
-		x:     ts.StructF1{ts.StructF{"NotEqual"}, "NotEqual"},
-		y:     ts.StructF1{ts.StructF{"not_equal"}, "not_equal"},
-		wantDiff: `
-{teststructs.StructF1}.StructF.X:
-	-: "NotEqual"
-	+: "not_equal"
-{teststructs.StructF1}.X:
-	-: "NotEqual"
-	+: "not_equal"`,
-	}, {
-		label: label + "StructF1",
-		x:     &ts.StructF1{ts.StructF{"NotEqual"}, "NotEqual"},
-		y:     &ts.StructF1{ts.StructF{"not_equal"}, "not_equal"},
-	}, {
-		label: label + "StructA2",
-		x:     ts.StructA2{&ts.StructA{"NotEqual"}, "equal"},
-		y:     ts.StructA2{&ts.StructA{"not_equal"}, "equal"},
-	}, {
-		label:    label + "StructA2",
-		x:        ts.StructA2{&ts.StructA{"NotEqual"}, "NotEqual"},
-		y:        ts.StructA2{&ts.StructA{"not_equal"}, "not_equal"},
-		wantDiff: "{teststructs.StructA2}.X:\n\t-: \"NotEqual\"\n\t+: \"not_equal\"\n",
-	}, {
-		label: label + "StructA2",
-		x:     &ts.StructA2{&ts.StructA{"NotEqual"}, "equal"},
-		y:     &ts.StructA2{&ts.StructA{"not_equal"}, "equal"},
-	}, {
-		label:    label + "StructA2",
-		x:        &ts.StructA2{&ts.StructA{"NotEqual"}, "NotEqual"},
-		y:        &ts.StructA2{&ts.StructA{"not_equal"}, "not_equal"},
-		wantDiff: "{*teststructs.StructA2}.X:\n\t-: \"NotEqual\"\n\t+: \"not_equal\"\n",
-	}, {
-		label: label + "StructB2",
-		x:     ts.StructB2{&ts.StructB{"NotEqual"}, "equal"},
-		y:     ts.StructB2{&ts.StructB{"not_equal"}, "equal"},
-	}, {
-		label:    label + "StructB2",
-		x:        ts.StructB2{&ts.StructB{"NotEqual"}, "NotEqual"},
-		y:        ts.StructB2{&ts.StructB{"not_equal"}, "not_equal"},
-		wantDiff: "{teststructs.StructB2}.X:\n\t-: \"NotEqual\"\n\t+: \"not_equal\"\n",
-	}, {
-		label: label + "StructB2",
-		x:     &ts.StructB2{&ts.StructB{"NotEqual"}, "equal"},
-		y:     &ts.StructB2{&ts.StructB{"not_equal"}, "equal"},
-	}, {
-		label:    label + "StructB2",
-		x:        &ts.StructB2{&ts.StructB{"NotEqual"}, "NotEqual"},
-		y:        &ts.StructB2{&ts.StructB{"not_equal"}, "not_equal"},
-		wantDiff: "{*teststructs.StructB2}.X:\n\t-: \"NotEqual\"\n\t+: \"not_equal\"\n",
-	}, {
-		label: label + "StructC2",
-		x:     ts.StructC2{&ts.StructC{"NotEqual"}, "NotEqual"},
-		y:     ts.StructC2{&ts.StructC{"not_equal"}, "not_equal"},
-	}, {
-		label: label + "StructC2",
-		x:     &ts.StructC2{&ts.StructC{"NotEqual"}, "NotEqual"},
-		y:     &ts.StructC2{&ts.StructC{"not_equal"}, "not_equal"},
-	}, {
-		label: label + "StructD2",
-		x:     ts.StructD2{&ts.StructD{"NotEqual"}, "NotEqual"},
-		y:     ts.StructD2{&ts.StructD{"not_equal"}, "not_equal"},
-	}, {
-		label: label + "StructD2",
-		x:     &ts.StructD2{&ts.StructD{"NotEqual"}, "NotEqual"},
-		y:     &ts.StructD2{&ts.StructD{"not_equal"}, "not_equal"},
-	}, {
-		label: label + "StructE2",
-		x:     ts.StructE2{&ts.StructE{"NotEqual"}, "NotEqual"},
-		y:     ts.StructE2{&ts.StructE{"not_equal"}, "not_equal"},
-	}, {
-		label: label + "StructE2",
-		x:     &ts.StructE2{&ts.StructE{"NotEqual"}, "NotEqual"},
-		y:     &ts.StructE2{&ts.StructE{"not_equal"}, "not_equal"},
-	}, {
-		label: label + "StructF2",
-		x:     ts.StructF2{&ts.StructF{"NotEqual"}, "NotEqual"},
-		y:     ts.StructF2{&ts.StructF{"not_equal"}, "not_equal"},
-	}, {
-		label: label + "StructF2",
-		x:     &ts.StructF2{&ts.StructF{"NotEqual"}, "NotEqual"},
-		y:     &ts.StructF2{&ts.StructF{"not_equal"}, "not_equal"},
-	}, {
-		label:    label + "StructNo",
-		x:        ts.StructNo{"NotEqual"},
-		y:        ts.StructNo{"not_equal"},
-		wantDiff: "{teststructs.StructNo}.X:\n\t-: \"NotEqual\"\n\t+: \"not_equal\"\n",
-	}, {
-		label: label + "AssignA",
-		x:     ts.AssignA(func() int { return 0 }),
-		y:     ts.AssignA(func() int { return 1 }),
-	}, {
-		label: label + "AssignB",
-		x:     ts.AssignB(struct{ A int }{0}),
-		y:     ts.AssignB(struct{ A int }{1}),
-	}, {
-		label: label + "AssignC",
-		x:     ts.AssignC(make(chan bool)),
-		y:     ts.AssignC(make(chan bool)),
-	}, {
-		label: label + "AssignD",
-		x:     ts.AssignD(make(chan bool)),
-		y:     ts.AssignD(make(chan bool)),
-	}}
-}
-
-func project1Tests() []test {
-	const label = "Project1"
-
-	ignoreUnexported := cmpopts.IgnoreUnexported(
-		ts.EagleImmutable{},
-		ts.DreamerImmutable{},
-		ts.SlapImmutable{},
-		ts.GoatImmutable{},
-		ts.DonkeyImmutable{},
-		ts.LoveRadius{},
-		ts.SummerLove{},
-		ts.SummerLoveSummary{},
-	)
-
-	createEagle := func() ts.Eagle {
-		return ts.Eagle{
-			Name:   "eagle",
-			Hounds: []string{"buford", "tannen"},
-			Desc:   "some description",
-			Dreamers: []ts.Dreamer{{}, {
-				Name: "dreamer2",
-				Animal: []interface{}{
-					ts.Goat{
-						Target: "corporation",
-						Immutable: &ts.GoatImmutable{
-							ID:      "southbay",
-							State:   (*pb.Goat_States)(intPtr(5)),
-							Started: now,
-						},
-					},
-					ts.Donkey{},
-				},
-				Amoeba: 53,
-			}},
-			Slaps: []ts.Slap{{
-				Name: "slapID",
-				Args: &pb.MetaData{Stringer: pb.Stringer{"metadata"}},
-				Immutable: &ts.SlapImmutable{
-					ID:       "immutableSlap",
-					MildSlap: true,
-					Started:  now,
-					LoveRadius: &ts.LoveRadius{
-						Summer: &ts.SummerLove{
-							Summary: &ts.SummerLoveSummary{
-								Devices:    []string{"foo", "bar", "baz"},
-								ChangeType: []pb.SummerType{1, 2, 3},
-							},
-						},
-					},
-				},
-			}},
-			Immutable: &ts.EagleImmutable{
-				ID:          "eagleID",
-				Birthday:    now,
-				MissingCall: (*pb.Eagle_MissingCalls)(intPtr(55)),
-			},
-		}
-	}
-
-	return []test{{
-		label: label,
-		x: ts.Eagle{Slaps: []ts.Slap{{
-			Args: &pb.MetaData{Stringer: pb.Stringer{"metadata"}},
-		}}},
-		y: ts.Eagle{Slaps: []ts.Slap{{
-			Args: &pb.MetaData{Stringer: pb.Stringer{"metadata"}},
-		}}},
-		wantPanic: "cannot handle unexported field",
-	}, {
-		label: label,
-		x: ts.Eagle{Slaps: []ts.Slap{{
-			Args: &pb.MetaData{Stringer: pb.Stringer{"metadata"}},
-		}}},
-		y: ts.Eagle{Slaps: []ts.Slap{{
-			Args: &pb.MetaData{Stringer: pb.Stringer{"metadata"}},
-		}}},
-		opts: []cmp.Option{cmp.Comparer(pb.Equal)},
-	}, {
-		label: label,
-		x: ts.Eagle{Slaps: []ts.Slap{{}, {}, {}, {}, {
-			Args: &pb.MetaData{Stringer: pb.Stringer{"metadata"}},
-		}}},
-		y: ts.Eagle{Slaps: []ts.Slap{{}, {}, {}, {}, {
-			Args: &pb.MetaData{Stringer: pb.Stringer{"metadata2"}},
-		}}},
-		opts:     []cmp.Option{cmp.Comparer(pb.Equal)},
-		wantDiff: "{teststructs.Eagle}.Slaps[4].Args:\n\t-: \"metadata\"\n\t+: \"metadata2\"\n",
-	}, {
-		label: label,
-		x:     createEagle(),
-		y:     createEagle(),
-		opts:  []cmp.Option{ignoreUnexported, cmp.Comparer(pb.Equal)},
-	}, {
-		label: label,
-		x: func() ts.Eagle {
-			eg := createEagle()
-			eg.Dreamers[1].Animal[0].(ts.Goat).Immutable.ID = "southbay2"
-			eg.Dreamers[1].Animal[0].(ts.Goat).Immutable.State = (*pb.Goat_States)(intPtr(6))
-			eg.Slaps[0].Immutable.MildSlap = false
-			return eg
-		}(),
-		y: func() ts.Eagle {
-			eg := createEagle()
-			devs := eg.Slaps[0].Immutable.LoveRadius.Summer.Summary.Devices
-			eg.Slaps[0].Immutable.LoveRadius.Summer.Summary.Devices = devs[:1]
-			return eg
-		}(),
-		opts: []cmp.Option{ignoreUnexported, cmp.Comparer(pb.Equal)},
-		wantDiff: `
-{teststructs.Eagle}.Dreamers[1].Animal[0].(teststructs.Goat).Immutable.ID:
-	-: "southbay2"
-	+: "southbay"
-*{teststructs.Eagle}.Dreamers[1].Animal[0].(teststructs.Goat).Immutable.State:
-	-: testprotos.Goat_States(6)
-	+: testprotos.Goat_States(5)
-{teststructs.Eagle}.Slaps[0].Immutable.MildSlap:
-	-: false
-	+: true
-{teststructs.Eagle}.Slaps[0].Immutable.LoveRadius.Summer.Summary.Devices[1->?]:
-	-: "bar"
-	+: <non-existent>
-{teststructs.Eagle}.Slaps[0].Immutable.LoveRadius.Summer.Summary.Devices[2->?]:
-	-: "baz"
-	+: <non-existent>`,
-	}}
-}
-
-type germSorter []*pb.Germ
-
-func (gs germSorter) Len() int           { return len(gs) }
-func (gs germSorter) Less(i, j int) bool { return gs[i].String() < gs[j].String() }
-func (gs germSorter) Swap(i, j int)      { gs[i], gs[j] = gs[j], gs[i] }
-
-func project2Tests() []test {
-	const label = "Project2"
-
-	sortGerms := cmp.FilterValues(func(x, y []*pb.Germ) bool {
-		ok1 := sort.IsSorted(germSorter(x))
-		ok2 := sort.IsSorted(germSorter(y))
-		return !ok1 || !ok2
-	}, cmp.Transformer("Sort", func(in []*pb.Germ) []*pb.Germ {
-		out := append([]*pb.Germ(nil), in...) // Make copy
-		sort.Sort(germSorter(out))
-		return out
-	}))
-
-	equalDish := cmp.Comparer(func(x, y *ts.Dish) bool {
-		if x == nil || y == nil {
-			return x == nil && y == nil
-		}
-		px, err1 := x.Proto()
-		py, err2 := y.Proto()
-		if err1 != nil || err2 != nil {
-			return err1 == err2
-		}
-		return pb.Equal(px, py)
-	})
-
-	createBatch := func() ts.GermBatch {
-		return ts.GermBatch{
-			DirtyGerms: map[int32][]*pb.Germ{
-				17: {
-					{Stringer: pb.Stringer{"germ1"}},
-				},
-				18: {
-					{Stringer: pb.Stringer{"germ2"}},
-					{Stringer: pb.Stringer{"germ3"}},
-					{Stringer: pb.Stringer{"germ4"}},
-				},
-			},
-			GermMap: map[int32]*pb.Germ{
-				13: {Stringer: pb.Stringer{"germ13"}},
-				21: {Stringer: pb.Stringer{"germ21"}},
-			},
-			DishMap: map[int32]*ts.Dish{
-				0: ts.CreateDish(nil, io.EOF),
-				1: ts.CreateDish(nil, io.ErrUnexpectedEOF),
-				2: ts.CreateDish(&pb.Dish{Stringer: pb.Stringer{"dish"}}, nil),
-			},
-			HasPreviousResult: true,
-			DirtyID:           10,
-			GermStrain:        421,
-			InfectedAt:        now,
-		}
-	}
-
-	return []test{{
-		label:     label,
-		x:         createBatch(),
-		y:         createBatch(),
-		wantPanic: "cannot handle unexported field",
-	}, {
-		label: label,
-		x:     createBatch(),
-		y:     createBatch(),
-		opts:  []cmp.Option{cmp.Comparer(pb.Equal), sortGerms, equalDish},
-	}, {
-		label: label,
-		x:     createBatch(),
-		y: func() ts.GermBatch {
-			gb := createBatch()
-			s := gb.DirtyGerms[18]
-			s[0], s[1], s[2] = s[1], s[2], s[0]
-			return gb
-		}(),
-		opts: []cmp.Option{cmp.Comparer(pb.Equal), equalDish},
-		wantDiff: `
-{teststructs.GermBatch}.DirtyGerms[18][0->?]:
-	-: "germ2"
-	+: <non-existent>
-{teststructs.GermBatch}.DirtyGerms[18][?->2]:
-	-: <non-existent>
-	+: "germ2"`,
-	}, {
-		label: label,
-		x:     createBatch(),
-		y: func() ts.GermBatch {
-			gb := createBatch()
-			s := gb.DirtyGerms[18]
-			s[0], s[1], s[2] = s[1], s[2], s[0]
-			return gb
-		}(),
-		opts: []cmp.Option{cmp.Comparer(pb.Equal), sortGerms, equalDish},
-	}, {
-		label: label,
-		x: func() ts.GermBatch {
-			gb := createBatch()
-			delete(gb.DirtyGerms, 17)
-			gb.DishMap[1] = nil
-			return gb
-		}(),
-		y: func() ts.GermBatch {
-			gb := createBatch()
-			gb.DirtyGerms[18] = gb.DirtyGerms[18][:2]
-			gb.GermStrain = 22
-			return gb
-		}(),
-		opts: []cmp.Option{cmp.Comparer(pb.Equal), sortGerms, equalDish},
-		wantDiff: `
-{teststructs.GermBatch}.DirtyGerms[17]:
-	-: <non-existent>
-	+: []*testprotos.Germ{"germ1"}
-{teststructs.GermBatch}.DirtyGerms[18][2->?]:
-	-: "germ4"
-	+: <non-existent>
-{teststructs.GermBatch}.DishMap[1]:
-	-: (*teststructs.Dish)(nil)
-	+: &teststructs.Dish{err: &errors.errorString{s: "unexpected EOF"}}
-{teststructs.GermBatch}.GermStrain:
-	-: 421
-	+: 22`,
-	}}
-}
-
-func project3Tests() []test {
-	const label = "Project3"
-
-	allowVisibility := cmp.AllowUnexported(ts.Dirt{})
-
-	ignoreLocker := cmpopts.IgnoreInterfaces(struct{ sync.Locker }{})
-
-	transformProtos := cmp.Transformer("", func(x pb.Dirt) *pb.Dirt {
-		return &x
-	})
-
-	equalTable := cmp.Comparer(func(x, y ts.Table) bool {
-		tx, ok1 := x.(*ts.MockTable)
-		ty, ok2 := y.(*ts.MockTable)
-		if !ok1 || !ok2 {
-			panic("table type must be MockTable")
-		}
-		return cmp.Equal(tx.State(), ty.State())
-	})
-
-	createDirt := func() (d ts.Dirt) {
-		d.SetTable(ts.CreateMockTable([]string{"a", "b", "c"}))
-		d.SetTimestamp(12345)
-		d.Discord = 554
-		d.Proto = pb.Dirt{Stringer: pb.Stringer{"proto"}}
-		d.SetWizard(map[string]*pb.Wizard{
-			"harry": {Stringer: pb.Stringer{"potter"}},
-			"albus": {Stringer: pb.Stringer{"dumbledore"}},
-		})
-		d.SetLastTime(54321)
-		return d
-	}
-
-	return []test{{
-		label:     label,
-		x:         createDirt(),
-		y:         createDirt(),
-		wantPanic: "cannot handle unexported field",
-	}, {
-		label:     label,
-		x:         createDirt(),
-		y:         createDirt(),
-		opts:      []cmp.Option{allowVisibility, ignoreLocker, cmp.Comparer(pb.Equal), equalTable},
-		wantPanic: "cannot handle unexported field",
-	}, {
-		label: label,
-		x:     createDirt(),
-		y:     createDirt(),
-		opts:  []cmp.Option{allowVisibility, transformProtos, ignoreLocker, cmp.Comparer(pb.Equal), equalTable},
-	}, {
-		label: label,
-		x: func() ts.Dirt {
-			d := createDirt()
-			d.SetTable(ts.CreateMockTable([]string{"a", "c"}))
-			d.Proto = pb.Dirt{Stringer: pb.Stringer{"blah"}}
-			return d
-		}(),
-		y: func() ts.Dirt {
-			d := createDirt()
-			d.Discord = 500
-			d.SetWizard(map[string]*pb.Wizard{
-				"harry": {Stringer: pb.Stringer{"otter"}},
-			})
-			return d
-		}(),
-		opts: []cmp.Option{allowVisibility, transformProtos, ignoreLocker, cmp.Comparer(pb.Equal), equalTable},
-		wantDiff: `
-{teststructs.Dirt}.table:
-	-: &teststructs.MockTable{state: []string{"a", "c"}}
-	+: &teststructs.MockTable{state: []string{"a", "b", "c"}}
-{teststructs.Dirt}.Discord:
-	-: teststructs.DiscordState(554)
-	+: teststructs.DiscordState(500)
-λ({teststructs.Dirt}.Proto):
-	-: "blah"
-	+: "proto"
-{teststructs.Dirt}.wizard["albus"]:
-	-: "dumbledore"
-	+: <non-existent>
-{teststructs.Dirt}.wizard["harry"]:
-	-: "potter"
-	+: "otter"`,
-	}}
-}
-
-func project4Tests() []test {
-	const label = "Project4"
-
-	allowVisibility := cmp.AllowUnexported(
-		ts.Cartel{},
-		ts.Headquarter{},
-		ts.Poison{},
-	)
-
-	transformProtos := cmp.Transformer("", func(x pb.Restrictions) *pb.Restrictions {
-		return &x
-	})
-
-	createCartel := func() ts.Cartel {
-		var p ts.Poison
-		p.SetPoisonType(5)
-		p.SetExpiration(now)
-		p.SetManufactuer("acme")
-
-		var hq ts.Headquarter
-		hq.SetID(5)
-		hq.SetLocation("moon")
-		hq.SetSubDivisions([]string{"alpha", "bravo", "charlie"})
-		hq.SetMetaData(&pb.MetaData{Stringer: pb.Stringer{"metadata"}})
-		hq.SetPublicMessage([]byte{1, 2, 3, 4, 5})
-		hq.SetHorseBack("abcdef")
-		hq.SetStatus(44)
-
-		var c ts.Cartel
-		c.Headquarter = hq
-		c.SetSource("mars")
-		c.SetCreationTime(now)
-		c.SetBoss("al capone")
-		c.SetPoisons([]*ts.Poison{&p})
-
-		return c
-	}
-
-	return []test{{
-		label:     label,
-		x:         createCartel(),
-		y:         createCartel(),
-		wantPanic: "cannot handle unexported field",
-	}, {
-		label:     label,
-		x:         createCartel(),
-		y:         createCartel(),
-		opts:      []cmp.Option{allowVisibility, cmp.Comparer(pb.Equal)},
-		wantPanic: "cannot handle unexported field",
-	}, {
-		label: label,
-		x:     createCartel(),
-		y:     createCartel(),
-		opts:  []cmp.Option{allowVisibility, transformProtos, cmp.Comparer(pb.Equal)},
-	}, {
-		label: label,
-		x: func() ts.Cartel {
-			d := createCartel()
-			var p1, p2 ts.Poison
-			p1.SetPoisonType(1)
-			p1.SetExpiration(now)
-			p1.SetManufactuer("acme")
-			p2.SetPoisonType(2)
-			p2.SetManufactuer("acme2")
-			d.SetPoisons([]*ts.Poison{&p1, &p2})
-			return d
-		}(),
-		y: func() ts.Cartel {
-			d := createCartel()
-			d.SetSubDivisions([]string{"bravo", "charlie"})
-			d.SetPublicMessage([]byte{1, 2, 4, 3, 5})
-			return d
-		}(),
-		opts: []cmp.Option{allowVisibility, transformProtos, cmp.Comparer(pb.Equal)},
-		wantDiff: `
-{teststructs.Cartel}.Headquarter.subDivisions[0->?]:
-	-: "alpha"
-	+: <non-existent>
-{teststructs.Cartel}.Headquarter.publicMessage[2]:
-	-: 0x03
-	+: 0x04
-{teststructs.Cartel}.Headquarter.publicMessage[3]:
-	-: 0x04
-	+: 0x03
-{teststructs.Cartel}.poisons[0].poisonType:
-	-: testprotos.PoisonType(1)
-	+: testprotos.PoisonType(5)
-{teststructs.Cartel}.poisons[1->?]:
-	-: &teststructs.Poison{poisonType: testprotos.PoisonType(2), manufactuer: "acme2"}
-	+: <non-existent>`,
-	}}
-}
-
-// TODO: Delete this hack when we drop Go1.6 support.
-func tRunParallel(t *testing.T, name string, f func(t *testing.T)) {
-	type runner interface {
-		Run(string, func(t *testing.T)) bool
-	}
-	var ti interface{} = t
-	if r, ok := ti.(runner); ok {
-		r.Run(name, func(t *testing.T) {
-			t.Parallel()
-			f(t)
-		})
-	} else {
-		// Cannot run sub-tests in parallel in Go1.6.
-		t.Logf("Test: %s", name)
-		f(t)
-	}
-}
diff --git a/vendor/github.com/google/go-cmp/cmp/example_test.go b/vendor/github.com/google/go-cmp/cmp/example_test.go
deleted file mode 100644
index 8729db3..0000000
--- a/vendor/github.com/google/go-cmp/cmp/example_test.go
+++ /dev/null
@@ -1,374 +0,0 @@
-// Copyright 2017, The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE.md file.
-
-package cmp_test
-
-import (
-	"fmt"
-	"math"
-	"reflect"
-	"sort"
-	"strings"
-
-	"github.com/google/go-cmp/cmp"
-)
-
-// TODO: Re-write these examples in terms of how you actually use the
-// fundamental options and filters and not in terms of what cool things you can
-// do with them since that overlaps with cmp/cmpopts.
-
-// Use Diff for printing out human-readable errors for test cases comparing
-// nested or structured data.
-func ExampleDiff_testing() {
-	// Code under test:
-	type ShipManifest struct {
-		Name     string
-		Crew     map[string]string
-		Androids int
-		Stolen   bool
-	}
-
-	// AddCrew tries to add the given crewmember to the manifest.
-	AddCrew := func(m *ShipManifest, name, title string) {
-		if m.Crew == nil {
-			m.Crew = make(map[string]string)
-		}
-		m.Crew[title] = name
-	}
-
-	// Test function:
-	tests := []struct {
-		desc        string
-		before      *ShipManifest
-		name, title string
-		after       *ShipManifest
-	}{
-		{
-			desc:   "add to empty",
-			before: &ShipManifest{},
-			name:   "Zaphod Beeblebrox",
-			title:  "Galactic President",
-			after: &ShipManifest{
-				Crew: map[string]string{
-					"Zaphod Beeblebrox": "Galactic President",
-				},
-			},
-		},
-		{
-			desc: "add another",
-			before: &ShipManifest{
-				Crew: map[string]string{
-					"Zaphod Beeblebrox": "Galactic President",
-				},
-			},
-			name:  "Trillian",
-			title: "Human",
-			after: &ShipManifest{
-				Crew: map[string]string{
-					"Zaphod Beeblebrox": "Galactic President",
-					"Trillian":          "Human",
-				},
-			},
-		},
-		{
-			desc: "overwrite",
-			before: &ShipManifest{
-				Crew: map[string]string{
-					"Zaphod Beeblebrox": "Galactic President",
-				},
-			},
-			name:  "Zaphod Beeblebrox",
-			title: "Just this guy, you know?",
-			after: &ShipManifest{
-				Crew: map[string]string{
-					"Zaphod Beeblebrox": "Just this guy, you know?",
-				},
-			},
-		},
-	}
-
-	var t fakeT
-	for _, test := range tests {
-		AddCrew(test.before, test.name, test.title)
-		if diff := cmp.Diff(test.before, test.after); diff != "" {
-			t.Errorf("%s: after AddCrew, manifest differs: (-got +want)\n%s", test.desc, diff)
-		}
-	}
-
-	// Output:
-	// add to empty: after AddCrew, manifest differs: (-got +want)
-	// {*cmp_test.ShipManifest}.Crew["Galactic President"]:
-	// 	-: "Zaphod Beeblebrox"
-	// 	+: <non-existent>
-	// {*cmp_test.ShipManifest}.Crew["Zaphod Beeblebrox"]:
-	// 	-: <non-existent>
-	// 	+: "Galactic President"
-	//
-	// add another: after AddCrew, manifest differs: (-got +want)
-	// {*cmp_test.ShipManifest}.Crew["Human"]:
-	// 	-: "Trillian"
-	// 	+: <non-existent>
-	// {*cmp_test.ShipManifest}.Crew["Trillian"]:
-	// 	-: <non-existent>
-	// 	+: "Human"
-	//
-	// overwrite: after AddCrew, manifest differs: (-got +want)
-	// {*cmp_test.ShipManifest}.Crew["Just this guy, you know?"]:
-	// 	-: "Zaphod Beeblebrox"
-	// 	+: <non-existent>
-	// {*cmp_test.ShipManifest}.Crew["Zaphod Beeblebrox"]:
-	// 	-: "Galactic President"
-	// 	+: "Just this guy, you know?"
-}
-
-// Approximate equality for floats can be handled by defining a custom
-// comparer on floats that determines two values to be equal if they are within
-// some range of each other.
-//
-// This example is for demonstrative purposes; use cmpopts.EquateApprox instead.
-func ExampleOption_approximateFloats() {
-	// This Comparer only operates on float64.
-	// To handle float32s, either define a similar function for that type
-	// or use a Transformer to convert float32s into float64s.
-	opt := cmp.Comparer(func(x, y float64) bool {
-		delta := math.Abs(x - y)
-		mean := math.Abs(x+y) / 2.0
-		return delta/mean < 0.00001
-	})
-
-	x := []float64{1.0, 1.1, 1.2, math.Pi}
-	y := []float64{1.0, 1.1, 1.2, 3.14159265359} // Accurate enough to Pi
-	z := []float64{1.0, 1.1, 1.2, 3.1415}        // Diverges too far from Pi
-
-	fmt.Println(cmp.Equal(x, y, opt))
-	fmt.Println(cmp.Equal(y, z, opt))
-	fmt.Println(cmp.Equal(z, x, opt))
-
-	// Output:
-	// true
-	// false
-	// false
-}
-
-// Normal floating-point arithmetic defines == to be false when comparing
-// NaN with itself. In certain cases, this is not the desired property.
-//
-// This example is for demonstrative purposes; use cmpopts.EquateNaNs instead.
-func ExampleOption_equalNaNs() {
-	// This Comparer only operates on float64.
-	// To handle float32s, either define a similar function for that type
-	// or use a Transformer to convert float32s into float64s.
-	opt := cmp.Comparer(func(x, y float64) bool {
-		return (math.IsNaN(x) && math.IsNaN(y)) || x == y
-	})
-
-	x := []float64{1.0, math.NaN(), math.E, -0.0, +0.0}
-	y := []float64{1.0, math.NaN(), math.E, -0.0, +0.0}
-	z := []float64{1.0, math.NaN(), math.Pi, -0.0, +0.0} // Pi constant instead of E
-
-	fmt.Println(cmp.Equal(x, y, opt))
-	fmt.Println(cmp.Equal(y, z, opt))
-	fmt.Println(cmp.Equal(z, x, opt))
-
-	// Output:
-	// true
-	// false
-	// false
-}
-
-// To have floating-point comparisons combine both properties of NaN being
-// equal to itself and also approximate equality of values, filters are needed
-// to restrict the scope of the comparison so that they are composable.
-//
-// This example is for demonstrative purposes;
-// use cmpopts.EquateNaNs and cmpopts.EquateApprox instead.
-func ExampleOption_equalNaNsAndApproximateFloats() {
-	alwaysEqual := cmp.Comparer(func(_, _ interface{}) bool { return true })
-
-	opts := cmp.Options{
-		// This option declares that a float64 comparison is equal only if
-		// both inputs are NaN.
-		cmp.FilterValues(func(x, y float64) bool {
-			return math.IsNaN(x) && math.IsNaN(y)
-		}, alwaysEqual),
-
-		// This option declares approximate equality on float64s only if
-		// both inputs are not NaN.
-		cmp.FilterValues(func(x, y float64) bool {
-			return !math.IsNaN(x) && !math.IsNaN(y)
-		}, cmp.Comparer(func(x, y float64) bool {
-			delta := math.Abs(x - y)
-			mean := math.Abs(x+y) / 2.0
-			return delta/mean < 0.00001
-		})),
-	}
-
-	x := []float64{math.NaN(), 1.0, 1.1, 1.2, math.Pi}
-	y := []float64{math.NaN(), 1.0, 1.1, 1.2, 3.14159265359} // Accurate enough to Pi
-	z := []float64{math.NaN(), 1.0, 1.1, 1.2, 3.1415}        // Diverges too far from Pi
-
-	fmt.Println(cmp.Equal(x, y, opts))
-	fmt.Println(cmp.Equal(y, z, opts))
-	fmt.Println(cmp.Equal(z, x, opts))
-
-	// Output:
-	// true
-	// false
-	// false
-}
-
-// Sometimes, an empty map or slice is considered equal to an allocated one
-// of zero length.
-//
-// This example is for demonstrative purposes; use cmpopts.EquateEmpty instead.
-func ExampleOption_equalEmpty() {
-	alwaysEqual := cmp.Comparer(func(_, _ interface{}) bool { return true })
-
-	// This option handles slices and maps of any type.
-	opt := cmp.FilterValues(func(x, y interface{}) bool {
-		vx, vy := reflect.ValueOf(x), reflect.ValueOf(y)
-		return (vx.IsValid() && vy.IsValid() && vx.Type() == vy.Type()) &&
-			(vx.Kind() == reflect.Slice || vx.Kind() == reflect.Map) &&
-			(vx.Len() == 0 && vy.Len() == 0)
-	}, alwaysEqual)
-
-	type S struct {
-		A []int
-		B map[string]bool
-	}
-	x := S{nil, make(map[string]bool, 100)}
-	y := S{make([]int, 0, 200), nil}
-	z := S{[]int{0}, nil} // []int has a single element (i.e., not empty)
-
-	fmt.Println(cmp.Equal(x, y, opt))
-	fmt.Println(cmp.Equal(y, z, opt))
-	fmt.Println(cmp.Equal(z, x, opt))
-
-	// Output:
-	// true
-	// false
-	// false
-}
-
-// Two slices may be considered equal if they have the same elements,
-// regardless of the order that they appear in. Transformations can be used
-// to sort the slice.
-//
-// This example is for demonstrative purposes; use cmpopts.SortSlices instead.
-func ExampleOption_sortedSlice() {
-	// This Transformer sorts a []int.
-	// Since the transformer transforms []int into []int, there is problem where
-	// this is recursively applied forever. To prevent this, use a FilterValues
-	// to first check for the condition upon which the transformer ought to apply.
-	trans := cmp.FilterValues(func(x, y []int) bool {
-		return !sort.IntsAreSorted(x) || !sort.IntsAreSorted(y)
-	}, cmp.Transformer("Sort", func(in []int) []int {
-		out := append([]int(nil), in...) // Copy input to avoid mutating it
-		sort.Ints(out)
-		return out
-	}))
-
-	x := struct{ Ints []int }{[]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}}
-	y := struct{ Ints []int }{[]int{2, 8, 0, 9, 6, 1, 4, 7, 3, 5}}
-	z := struct{ Ints []int }{[]int{0, 0, 1, 2, 3, 4, 5, 6, 7, 8}}
-
-	fmt.Println(cmp.Equal(x, y, trans))
-	fmt.Println(cmp.Equal(y, z, trans))
-	fmt.Println(cmp.Equal(z, x, trans))
-
-	// Output:
-	// true
-	// false
-	// false
-}
-
-type otherString string
-
-func (x otherString) Equal(y otherString) bool {
-	return strings.ToLower(string(x)) == strings.ToLower(string(y))
-}
-
-// If the Equal method defined on a type is not suitable, the type can be be
-// dynamically transformed to be stripped of the Equal method (or any method
-// for that matter).
-func ExampleOption_avoidEqualMethod() {
-	// Suppose otherString.Equal performs a case-insensitive equality,
-	// which is too loose for our needs.
-	// We can avoid the methods of otherString by declaring a new type.
-	type myString otherString
-
-	// This transformer converts otherString to myString, allowing Equal to use
-	// other Options to determine equality.
-	trans := cmp.Transformer("", func(in otherString) myString {
-		return myString(in)
-	})
-
-	x := []otherString{"foo", "bar", "baz"}
-	y := []otherString{"fOO", "bAr", "Baz"} // Same as before, but with different case
-
-	fmt.Println(cmp.Equal(x, y))        // Equal because of case-insensitivity
-	fmt.Println(cmp.Equal(x, y, trans)) // Not equal because of more exact equality
-
-	// Output:
-	// true
-	// false
-}
-
-func roundF64(z float64) float64 {
-	if z < 0 {
-		return math.Ceil(z - 0.5)
-	}
-	return math.Floor(z + 0.5)
-}
-
-// The complex numbers complex64 and complex128 can really just be decomposed
-// into a pair of float32 or float64 values. It would be convenient to be able
-// define only a single comparator on float64 and have float32, complex64, and
-// complex128 all be able to use that comparator. Transformations can be used
-// to handle this.
-func ExampleOption_transformComplex() {
-	opts := []cmp.Option{
-		// This transformer decomposes complex128 into a pair of float64s.
-		cmp.Transformer("T1", func(in complex128) (out struct{ Real, Imag float64 }) {
-			out.Real, out.Imag = real(in), imag(in)
-			return out
-		}),
-		// This transformer converts complex64 to complex128 to allow the
-		// above transform to take effect.
-		cmp.Transformer("T2", func(in complex64) complex128 {
-			return complex128(in)
-		}),
-		// This transformer converts float32 to float64.
-		cmp.Transformer("T3", func(in float32) float64 {
-			return float64(in)
-		}),
-		// This equality function compares float64s as rounded integers.
-		cmp.Comparer(func(x, y float64) bool {
-			return roundF64(x) == roundF64(y)
-		}),
-	}
-
-	x := []interface{}{
-		complex128(3.0), complex64(5.1 + 2.9i), float32(-1.2), float64(12.3),
-	}
-	y := []interface{}{
-		complex128(3.1), complex64(4.9 + 3.1i), float32(-1.3), float64(11.7),
-	}
-	z := []interface{}{
-		complex128(3.8), complex64(4.9 + 3.1i), float32(-1.3), float64(11.7),
-	}
-
-	fmt.Println(cmp.Equal(x, y, opts...))
-	fmt.Println(cmp.Equal(y, z, opts...))
-	fmt.Println(cmp.Equal(z, x, opts...))
-
-	// Output:
-	// true
-	// false
-	// false
-}
-
-type fakeT struct{}
-
-func (t fakeT) Errorf(format string, args ...interface{}) { fmt.Printf(format+"\n", args...) }
diff --git a/vendor/github.com/google/go-cmp/cmp/internal/diff/diff_test.go b/vendor/github.com/google/go-cmp/cmp/internal/diff/diff_test.go
deleted file mode 100644
index 5996ea2..0000000
--- a/vendor/github.com/google/go-cmp/cmp/internal/diff/diff_test.go
+++ /dev/null
@@ -1,467 +0,0 @@
-// Copyright 2017, The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE.md file.
-
-package diff
-
-import (
-	"fmt"
-	"math/rand"
-	"strings"
-	"testing"
-	"unicode"
-)
-
-func TestDifference(t *testing.T) {
-	tests := []struct {
-		// Before passing x and y to Difference, we strip all spaces so that
-		// they can be used by the test author to indicate a missing symbol
-		// in one of the lists.
-		x, y string
-		want string
-	}{{
-		x:    "",
-		y:    "",
-		want: "",
-	}, {
-		x:    "#",
-		y:    "#",
-		want: ".",
-	}, {
-		x:    "##",
-		y:    "# ",
-		want: ".X",
-	}, {
-		x:    "a#",
-		y:    "A ",
-		want: "MX",
-	}, {
-		x:    "#a",
-		y:    " A",
-		want: "XM",
-	}, {
-		x:    "# ",
-		y:    "##",
-		want: ".Y",
-	}, {
-		x:    " #",
-		y:    "@#",
-		want: "Y.",
-	}, {
-		x:    "@#",
-		y:    " #",
-		want: "X.",
-	}, {
-		x:    "##########0123456789",
-		y:    "          0123456789",
-		want: "XXXXXXXXXX..........",
-	}, {
-		x:    "          0123456789",
-		y:    "##########0123456789",
-		want: "YYYYYYYYYY..........",
-	}, {
-		x:    "#####0123456789#####",
-		y:    "     0123456789     ",
-		want: "XXXXX..........XXXXX",
-	}, {
-		x:    "     0123456789     ",
-		y:    "#####0123456789#####",
-		want: "YYYYY..........YYYYY",
-	}, {
-		x:    "01234##########56789",
-		y:    "01234          56789",
-		want: ".....XXXXXXXXXX.....",
-	}, {
-		x:    "01234          56789",
-		y:    "01234##########56789",
-		want: ".....YYYYYYYYYY.....",
-	}, {
-		x:    "0123456789##########",
-		y:    "0123456789          ",
-		want: "..........XXXXXXXXXX",
-	}, {
-		x:    "0123456789          ",
-		y:    "0123456789##########",
-		want: "..........YYYYYYYYYY",
-	}, {
-		x:    "abcdefghij0123456789",
-		y:    "ABCDEFGHIJ0123456789",
-		want: "MMMMMMMMMM..........",
-	}, {
-		x:    "ABCDEFGHIJ0123456789",
-		y:    "abcdefghij0123456789",
-		want: "MMMMMMMMMM..........",
-	}, {
-		x:    "01234abcdefghij56789",
-		y:    "01234ABCDEFGHIJ56789",
-		want: ".....MMMMMMMMMM.....",
-	}, {
-		x:    "01234ABCDEFGHIJ56789",
-		y:    "01234abcdefghij56789",
-		want: ".....MMMMMMMMMM.....",
-	}, {
-		x:    "0123456789abcdefghij",
-		y:    "0123456789ABCDEFGHIJ",
-		want: "..........MMMMMMMMMM",
-	}, {
-		x:    "0123456789ABCDEFGHIJ",
-		y:    "0123456789abcdefghij",
-		want: "..........MMMMMMMMMM",
-	}, {
-		x:    "ABCDEFGHIJ0123456789          ",
-		y:    "          0123456789abcdefghij",
-		want: "XXXXXXXXXX..........YYYYYYYYYY",
-	}, {
-		x:    "          0123456789abcdefghij",
-		y:    "ABCDEFGHIJ0123456789          ",
-		want: "YYYYYYYYYY..........XXXXXXXXXX",
-	}, {
-		x:    "ABCDE0123456789     FGHIJ",
-		y:    "     0123456789abcdefghij",
-		want: "XXXXX..........YYYYYMMMMM",
-	}, {
-		x:    "     0123456789abcdefghij",
-		y:    "ABCDE0123456789     FGHIJ",
-		want: "YYYYY..........XXXXXMMMMM",
-	}, {
-		x:    "ABCDE01234F G H I J 56789     ",
-		y:    "     01234 a b c d e56789fghij",
-		want: "XXXXX.....XYXYXYXYXY.....YYYYY",
-	}, {
-		x:    "     01234a b c d e 56789fghij",
-		y:    "ABCDE01234 F G H I J56789     ",
-		want: "YYYYY.....XYXYXYXYXY.....XXXXX",
-	}, {
-		x:    "FGHIJ01234ABCDE56789     ",
-		y:    "     01234abcde56789fghij",
-		want: "XXXXX.....MMMMM.....YYYYY",
-	}, {
-		x:    "     01234abcde56789fghij",
-		y:    "FGHIJ01234ABCDE56789     ",
-		want: "YYYYY.....MMMMM.....XXXXX",
-	}, {
-		x:    "ABCAB BA ",
-		y:    "  C BABAC",
-		want: "XX.X.Y..Y",
-	}, {
-		x:    "# ####  ###",
-		y:    "#y####yy###",
-		want: ".Y....YY...",
-	}, {
-		x:    "# #### # ##x#x",
-		y:    "#y####y y## # ",
-		want: ".Y....YXY..X.X",
-	}, {
-		x:    "###z#z###### x  #",
-		y:    "#y##Z#Z###### yy#",
-		want: ".Y..M.M......XYY.",
-	}, {
-		x:    "0 12z3x 456789 x x 0",
-		y:    "0y12Z3 y456789y y y0",
-		want: ".Y..M.XY......YXYXY.",
-	}, {
-		x:    "0 2 4 6 8 ..................abXXcdEXF.ghXi",
-		y:    " 1 3 5 7 9..................AB  CDE F.GH I",
-		want: "XYXYXYXYXY..................MMXXMM.X..MMXM",
-	}, {
-		x:    "I HG.F EDC  BA..................9 7 5 3 1 ",
-		y:    "iXhg.FXEdcXXba.................. 8 6 4 2 0",
-		want: "MYMM..Y.MMYYMM..................XYXYXYXYXY",
-	}, {
-		x:    "x1234",
-		y:    " 1234",
-		want: "X....",
-	}, {
-		x:    "x123x4",
-		y:    " 123 4",
-		want: "X...X.",
-	}, {
-		x:    "x1234x56",
-		y:    " 1234   ",
-		want: "X....XXX",
-	}, {
-		x:    "x1234xxx56",
-		y:    " 1234   56",
-		want: "X....XXX..",
-	}, {
-		x:    ".1234...ab",
-		y:    " 1234   AB",
-		want: "X....XXXMM",
-	}, {
-		x:    "x1234xxab.",
-		y:    " 1234  AB ",
-		want: "X....XXMMX",
-	}, {
-		x:    " 0123456789",
-		y:    "9012345678 ",
-		want: "Y.........X",
-	}, {
-		x:    "  0123456789",
-		y:    "8901234567  ",
-		want: "YY........XX",
-	}, {
-		x:    "   0123456789",
-		y:    "7890123456   ",
-		want: "YYY.......XXX",
-	}, {
-		x:    "    0123456789",
-		y:    "6789012345    ",
-		want: "YYYY......XXXX",
-	}, {
-		x:    "0123456789     ",
-		y:    "     5678901234",
-		want: "XXXXX.....YYYYY",
-	}, {
-		x:    "0123456789    ",
-		y:    "    4567890123",
-		want: "XXXX......YYYY",
-	}, {
-		x:    "0123456789   ",
-		y:    "   3456789012",
-		want: "XXX.......YYY",
-	}, {
-		x:    "0123456789  ",
-		y:    "  2345678901",
-		want: "XX........YY",
-	}, {
-		x:    "0123456789 ",
-		y:    " 1234567890",
-		want: "X.........Y",
-	}, {
-		x: "0123456789",
-		y: "9876543210",
-	}, {
-		x: "0123456789",
-		y: "6725819034",
-	}, {
-		x: "FBQMOIGTLN72X90E4SP651HKRJUDA83CVZW",
-		y: "5WHXO10R9IVKZLCTAJ8P3NSEQM472G6UBDF",
-	}}
-
-	for _, tt := range tests {
-		tRun(t, "", func(t *testing.T) {
-			x := strings.Replace(tt.x, " ", "", -1)
-			y := strings.Replace(tt.y, " ", "", -1)
-			es := testStrings(t, x, y)
-			if got := es.String(); got != tt.want {
-				t.Errorf("Difference(%s, %s):\ngot  %s\nwant %s", x, y, got, tt.want)
-			}
-		})
-	}
-}
-
-func TestDifferenceFuzz(t *testing.T) {
-	tests := []struct{ px, py, pm float32 }{
-		{px: 0.0, py: 0.0, pm: 0.1},
-		{px: 0.0, py: 0.1, pm: 0.0},
-		{px: 0.1, py: 0.0, pm: 0.0},
-		{px: 0.0, py: 0.1, pm: 0.1},
-		{px: 0.1, py: 0.0, pm: 0.1},
-		{px: 0.2, py: 0.2, pm: 0.2},
-		{px: 0.3, py: 0.1, pm: 0.2},
-		{px: 0.1, py: 0.3, pm: 0.2},
-		{px: 0.2, py: 0.2, pm: 0.2},
-		{px: 0.3, py: 0.3, pm: 0.3},
-		{px: 0.1, py: 0.1, pm: 0.5},
-		{px: 0.4, py: 0.1, pm: 0.5},
-		{px: 0.3, py: 0.2, pm: 0.5},
-		{px: 0.2, py: 0.3, pm: 0.5},
-		{px: 0.1, py: 0.4, pm: 0.5},
-	}
-
-	for i, tt := range tests {
-		tRun(t, fmt.Sprintf("P%d", i), func(t *testing.T) {
-			// Sweep from 1B to 1KiB.
-			for n := 1; n <= 1024; n <<= 1 {
-				tRun(t, fmt.Sprintf("N%d", n), func(t *testing.T) {
-					for j := 0; j < 10; j++ {
-						x, y := generateStrings(n, tt.px, tt.py, tt.pm, int64(j))
-						testStrings(t, x, y)
-					}
-				})
-			}
-		})
-	}
-}
-
-func benchmarkDifference(b *testing.B, n int) {
-	// TODO: Use testing.B.Run when we drop Go1.6 support.
-	x, y := generateStrings(n, 0.05, 0.05, 0.10, 0)
-	b.ReportAllocs()
-	b.SetBytes(int64(len(x) + len(y)))
-	for i := 0; i < b.N; i++ {
-		Difference(len(x), len(y), func(ix, iy int) Result {
-			return compareByte(x[ix], y[iy])
-		})
-	}
-}
-func BenchmarkDifference1K(b *testing.B)   { benchmarkDifference(b, 1<<10) }
-func BenchmarkDifference4K(b *testing.B)   { benchmarkDifference(b, 1<<12) }
-func BenchmarkDifference16K(b *testing.B)  { benchmarkDifference(b, 1<<14) }
-func BenchmarkDifference64K(b *testing.B)  { benchmarkDifference(b, 1<<16) }
-func BenchmarkDifference256K(b *testing.B) { benchmarkDifference(b, 1<<18) }
-func BenchmarkDifference1M(b *testing.B)   { benchmarkDifference(b, 1<<20) }
-
-func generateStrings(n int, px, py, pm float32, seed int64) (string, string) {
-	if px+py+pm > 1.0 {
-		panic("invalid probabilities")
-	}
-	py += px
-	pm += py
-
-	b := make([]byte, n)
-	r := rand.New(rand.NewSource(seed))
-	r.Read(b)
-
-	var x, y []byte
-	for len(b) > 0 {
-		switch p := r.Float32(); {
-		case p < px: // UniqueX
-			x = append(x, b[0])
-		case p < py: // UniqueY
-			y = append(y, b[0])
-		case p < pm: // Modified
-			x = append(x, 'A'+(b[0]%26))
-			y = append(y, 'a'+(b[0]%26))
-		default: // Identity
-			x = append(x, b[0])
-			y = append(y, b[0])
-		}
-		b = b[1:]
-	}
-	return string(x), string(y)
-}
-
-func testStrings(t *testing.T, x, y string) EditScript {
-	wantEq := x == y
-	eq, es := Difference(len(x), len(y), func(ix, iy int) Result {
-		return compareByte(x[ix], y[iy])
-	})
-	if eq != wantEq {
-		t.Errorf("equality mismatch: got %v, want %v", eq, wantEq)
-	}
-	if es != nil {
-		if es.LenX() != len(x) {
-			t.Errorf("es.LenX = %d, want %d", es.LenX(), len(x))
-		}
-		if es.LenY() != len(y) {
-			t.Errorf("es.LenY = %d, want %d", es.LenY(), len(y))
-		}
-		if got := (es.Dist() == 0); got != wantEq {
-			t.Errorf("violation of equality invariant: got %v, want %v", got, wantEq)
-		}
-		if !validateScript(x, y, es) {
-			t.Errorf("invalid edit script: %v", es)
-		}
-	}
-	return es
-}
-
-func validateScript(x, y string, es EditScript) bool {
-	var bx, by []byte
-	for _, e := range es {
-		switch e {
-		case Identity:
-			if !compareByte(x[len(bx)], y[len(by)]).Equal() {
-				return false
-			}
-			bx = append(bx, x[len(bx)])
-			by = append(by, y[len(by)])
-		case UniqueX:
-			bx = append(bx, x[len(bx)])
-		case UniqueY:
-			by = append(by, y[len(by)])
-		case Modified:
-			if !compareByte(x[len(bx)], y[len(by)]).Similar() {
-				return false
-			}
-			bx = append(bx, x[len(bx)])
-			by = append(by, y[len(by)])
-		}
-	}
-	return string(bx) == x && string(by) == y
-}
-
-// compareByte returns a Result where the result is Equal if x == y,
-// similar if x and y differ only in casing, and different otherwise.
-func compareByte(x, y byte) (r Result) {
-	switch {
-	case x == y:
-		return equalResult // Identity
-	case unicode.ToUpper(rune(x)) == unicode.ToUpper(rune(y)):
-		return similarResult // Modified
-	default:
-		return differentResult // UniqueX or UniqueY
-	}
-}
-
-var (
-	equalResult     = Result{NDiff: 0}
-	similarResult   = Result{NDiff: 1}
-	differentResult = Result{NDiff: 2}
-)
-
-func TestResult(t *testing.T) {
-	tests := []struct {
-		result      Result
-		wantEqual   bool
-		wantSimilar bool
-	}{
-		// equalResult is equal since NDiff == 0, by definition of Equal method.
-		{equalResult, true, true},
-		// similarResult is similar since it is a binary result where only one
-		// element was compared (i.e., Either NSame==1 or NDiff==1).
-		{similarResult, false, true},
-		// differentResult is different since there are enough differences that
-		// it isn't even considered similar.
-		{differentResult, false, false},
-
-		// Zero value is always equal.
-		{Result{NSame: 0, NDiff: 0}, true, true},
-
-		// Binary comparisons (where NSame+NDiff == 1) are always similar.
-		{Result{NSame: 1, NDiff: 0}, true, true},
-		{Result{NSame: 0, NDiff: 1}, false, true},
-
-		// More complex ratios. The exact ratio for similarity may change,
-		// and may require updates to these test cases.
-		{Result{NSame: 1, NDiff: 1}, false, true},
-		{Result{NSame: 1, NDiff: 2}, false, true},
-		{Result{NSame: 1, NDiff: 3}, false, false},
-		{Result{NSame: 2, NDiff: 1}, false, true},
-		{Result{NSame: 2, NDiff: 2}, false, true},
-		{Result{NSame: 2, NDiff: 3}, false, true},
-		{Result{NSame: 3, NDiff: 1}, false, true},
-		{Result{NSame: 3, NDiff: 2}, false, true},
-		{Result{NSame: 3, NDiff: 3}, false, true},
-		{Result{NSame: 1000, NDiff: 0}, true, true},
-		{Result{NSame: 1000, NDiff: 1}, false, true},
-		{Result{NSame: 1000, NDiff: 2}, false, true},
-		{Result{NSame: 0, NDiff: 1000}, false, false},
-		{Result{NSame: 1, NDiff: 1000}, false, false},
-		{Result{NSame: 2, NDiff: 1000}, false, false},
-	}
-
-	for _, tt := range tests {
-		if got := tt.result.Equal(); got != tt.wantEqual {
-			t.Errorf("%#v.Equal() = %v, want %v", tt.result, got, tt.wantEqual)
-		}
-		if got := tt.result.Similar(); got != tt.wantSimilar {
-			t.Errorf("%#v.Similar() = %v, want %v", tt.result, got, tt.wantSimilar)
-		}
-	}
-}
-
-// TODO: Delete this hack when we drop Go1.6 support.
-func tRun(t *testing.T, name string, f func(t *testing.T)) {
-	type runner interface {
-		Run(string, func(t *testing.T)) bool
-	}
-	var ti interface{} = t
-	if r, ok := ti.(runner); ok {
-		r.Run(name, f)
-	} else {
-		t.Logf("Test: %s", name)
-		f(t)
-	}
-}
diff --git a/vendor/github.com/google/go-cmp/cmp/internal/value/format_test.go b/vendor/github.com/google/go-cmp/cmp/internal/value/format_test.go
deleted file mode 100644
index 6498854..0000000
--- a/vendor/github.com/google/go-cmp/cmp/internal/value/format_test.go
+++ /dev/null
@@ -1,91 +0,0 @@
-// Copyright 2017, The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE.md file.
-
-package value
-
-import (
-	"bytes"
-	"io"
-	"reflect"
-	"testing"
-)
-
-func TestFormat(t *testing.T) {
-	type key struct {
-		a int
-		b string
-		c chan bool
-	}
-
-	tests := []struct {
-		in   interface{}
-		want string
-	}{{
-		in:   []int{},
-		want: "[]int{}",
-	}, {
-		in:   []int(nil),
-		want: "[]int(nil)",
-	}, {
-		in:   []int{1, 2, 3, 4, 5},
-		want: "[]int{1, 2, 3, 4, 5}",
-	}, {
-		in:   []interface{}{1, true, "hello", struct{ A, B int }{1, 2}},
-		want: "[]interface {}{1, true, \"hello\", struct { A int; B int }{A: 1, B: 2}}",
-	}, {
-		in:   []struct{ A, B int }{{1, 2}, {0, 4}, {}},
-		want: "[]struct { A int; B int }{{A: 1, B: 2}, {B: 4}, {}}",
-	}, {
-		in:   map[*int]string{new(int): "hello"},
-		want: "map[*int]string{0x00: \"hello\"}",
-	}, {
-		in:   map[key]string{{}: "hello"},
-		want: "map[value.key]string{{}: \"hello\"}",
-	}, {
-		in:   map[key]string{{a: 5, b: "key", c: make(chan bool)}: "hello"},
-		want: "map[value.key]string{{a: 5, b: \"key\", c: (chan bool)(0x00)}: \"hello\"}",
-	}, {
-		in:   map[io.Reader]string{new(bytes.Reader): "hello"},
-		want: "map[io.Reader]string{0x00: \"hello\"}",
-	}, {
-		in: func() interface{} {
-			var a = []interface{}{nil}
-			a[0] = a
-			return a
-		}(),
-		want: "[]interface {}{([]interface {})(0x00)}",
-	}, {
-		in: func() interface{} {
-			type A *A
-			var a A
-			a = &a
-			return a
-		}(),
-		want: "&(value.A)(0x00)",
-	}, {
-		in: func() interface{} {
-			type A map[*A]A
-			a := make(A)
-			a[&a] = a
-			return a
-		}(),
-		want: "value.A{0x00: 0x00}",
-	}, {
-		in: func() interface{} {
-			var a [2]interface{}
-			a[0] = &a
-			return a
-		}(),
-		want: "[2]interface {}{&[2]interface {}{(*[2]interface {})(0x00), interface {}(nil)}, interface {}(nil)}",
-	}}
-
-	formatFakePointers = true
-	defer func() { formatFakePointers = false }()
-	for i, tt := range tests {
-		got := Format(reflect.ValueOf(tt.in), true)
-		if got != tt.want {
-			t.Errorf("test %d, Format():\ngot  %q\nwant %q", i, got, tt.want)
-		}
-	}
-}
diff --git a/vendor/github.com/google/go-cmp/cmp/internal/value/sort_test.go b/vendor/github.com/google/go-cmp/cmp/internal/value/sort_test.go
deleted file mode 100644
index c5a6bbb..0000000
--- a/vendor/github.com/google/go-cmp/cmp/internal/value/sort_test.go
+++ /dev/null
@@ -1,152 +0,0 @@
-// Copyright 2017, The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE.md file.
-
-package value_test
-
-import (
-	"math"
-	"reflect"
-	"testing"
-
-	"github.com/google/go-cmp/cmp"
-	"github.com/google/go-cmp/cmp/internal/value"
-)
-
-func TestSortKeys(t *testing.T) {
-	type (
-		MyString string
-		MyArray  [2]int
-		MyStruct struct {
-			A MyString
-			B MyArray
-			C chan float64
-		}
-		EmptyStruct struct{}
-	)
-
-	opts := []cmp.Option{
-		cmp.Comparer(func(x, y float64) bool {
-			if math.IsNaN(x) && math.IsNaN(y) {
-				return true
-			}
-			return x == y
-		}),
-		cmp.Comparer(func(x, y complex128) bool {
-			rx, ix, ry, iy := real(x), imag(x), real(y), imag(y)
-			if math.IsNaN(rx) && math.IsNaN(ry) {
-				rx, ry = 0, 0
-			}
-			if math.IsNaN(ix) && math.IsNaN(iy) {
-				ix, iy = 0, 0
-			}
-			return rx == ry && ix == iy
-		}),
-		cmp.Comparer(func(x, y chan bool) bool { return true }),
-		cmp.Comparer(func(x, y chan int) bool { return true }),
-		cmp.Comparer(func(x, y chan float64) bool { return true }),
-		cmp.Comparer(func(x, y chan interface{}) bool { return true }),
-		cmp.Comparer(func(x, y *int) bool { return true }),
-	}
-
-	tests := []struct {
-		in   map[interface{}]bool // Set of keys to sort
-		want []interface{}
-	}{{
-		in:   map[interface{}]bool{1: true, 2: true, 3: true},
-		want: []interface{}{1, 2, 3},
-	}, {
-		in: map[interface{}]bool{
-			nil:                    true,
-			true:                   true,
-			false:                  true,
-			-5:                     true,
-			-55:                    true,
-			-555:                   true,
-			uint(1):                true,
-			uint(11):               true,
-			uint(111):              true,
-			"abc":                  true,
-			"abcd":                 true,
-			"abcde":                true,
-			"foo":                  true,
-			"bar":                  true,
-			MyString("abc"):        true,
-			MyString("abcd"):       true,
-			MyString("abcde"):      true,
-			new(int):               true,
-			new(int):               true,
-			make(chan bool):        true,
-			make(chan bool):        true,
-			make(chan int):         true,
-			make(chan interface{}): true,
-			math.Inf(+1):           true,
-			math.Inf(-1):           true,
-			1.2345:                 true,
-			12.345:                 true,
-			123.45:                 true,
-			1234.5:                 true,
-			0 + 0i:                 true,
-			1 + 0i:                 true,
-			2 + 0i:                 true,
-			0 + 1i:                 true,
-			0 + 2i:                 true,
-			0 + 3i:                 true,
-			[2]int{2, 3}:           true,
-			[2]int{4, 0}:           true,
-			[2]int{2, 4}:           true,
-			MyArray([2]int{2, 4}):  true,
-			EmptyStruct{}:          true,
-			MyStruct{
-				"bravo", [2]int{2, 3}, make(chan float64),
-			}: true,
-			MyStruct{
-				"alpha", [2]int{3, 3}, make(chan float64),
-			}: true,
-		},
-		want: []interface{}{
-			nil, false, true,
-			-555, -55, -5, uint(1), uint(11), uint(111),
-			math.Inf(-1), 1.2345, 12.345, 123.45, 1234.5, math.Inf(+1),
-			(0 + 0i), (0 + 1i), (0 + 2i), (0 + 3i), (1 + 0i), (2 + 0i),
-			[2]int{2, 3}, [2]int{2, 4}, [2]int{4, 0}, MyArray([2]int{2, 4}),
-			make(chan bool), make(chan bool), make(chan int), make(chan interface{}),
-			new(int), new(int),
-			"abc", "abcd", "abcde", "bar", "foo",
-			MyString("abc"), MyString("abcd"), MyString("abcde"),
-			EmptyStruct{},
-			MyStruct{"alpha", [2]int{3, 3}, make(chan float64)},
-			MyStruct{"bravo", [2]int{2, 3}, make(chan float64)},
-		},
-	}, {
-		// NaN values cannot be properly deduplicated.
-		// This is okay since map entries with NaN in the keys cannot be
-		// retrieved anyways.
-		in: map[interface{}]bool{
-			math.NaN():                      true,
-			math.NaN():                      true,
-			complex(0, math.NaN()):          true,
-			complex(0, math.NaN()):          true,
-			complex(math.NaN(), 0):          true,
-			complex(math.NaN(), 0):          true,
-			complex(math.NaN(), math.NaN()): true,
-		},
-		want: []interface{}{
-			math.NaN(), math.NaN(), math.NaN(), math.NaN(),
-			complex(math.NaN(), math.NaN()), complex(math.NaN(), math.NaN()),
-			complex(math.NaN(), 0), complex(math.NaN(), 0), complex(math.NaN(), 0), complex(math.NaN(), 0),
-			complex(0, math.NaN()), complex(0, math.NaN()), complex(0, math.NaN()), complex(0, math.NaN()),
-		},
-	}}
-
-	for i, tt := range tests {
-		keys := append(reflect.ValueOf(tt.in).MapKeys(), reflect.ValueOf(tt.in).MapKeys()...)
-		var got []interface{}
-		for _, k := range value.SortKeys(keys) {
-			got = append(got, k.Interface())
-		}
-		if d := cmp.Diff(got, tt.want, opts...); d != "" {
-			t.Errorf("test %d, Sort() mismatch (-got +want):\n%s", i, d)
-		}
-	}
-}
diff --git a/vendor/github.com/google/go-cmp/cmp/options_test.go b/vendor/github.com/google/go-cmp/cmp/options_test.go
deleted file mode 100644
index 009b524..0000000
--- a/vendor/github.com/google/go-cmp/cmp/options_test.go
+++ /dev/null
@@ -1,231 +0,0 @@
-// Copyright 2017, The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE.md file.
-
-package cmp
-
-import (
-	"io"
-	"reflect"
-	"strings"
-	"testing"
-
-	ts "github.com/google/go-cmp/cmp/internal/teststructs"
-)
-
-// Test that the creation of Option values with non-sensible inputs produces
-// a run-time panic with a decent error message
-func TestOptionPanic(t *testing.T) {
-	type myBool bool
-	tests := []struct {
-		label     string        // Test description
-		fnc       interface{}   // Option function to call
-		args      []interface{} // Arguments to pass in
-		wantPanic string        // Expected panic message
-	}{{
-		label: "AllowUnexported",
-		fnc:   AllowUnexported,
-		args:  []interface{}{},
-	}, {
-		label:     "AllowUnexported",
-		fnc:       AllowUnexported,
-		args:      []interface{}{1},
-		wantPanic: "invalid struct type",
-	}, {
-		label: "AllowUnexported",
-		fnc:   AllowUnexported,
-		args:  []interface{}{ts.StructA{}},
-	}, {
-		label: "AllowUnexported",
-		fnc:   AllowUnexported,
-		args:  []interface{}{ts.StructA{}, ts.StructB{}, ts.StructA{}},
-	}, {
-		label:     "AllowUnexported",
-		fnc:       AllowUnexported,
-		args:      []interface{}{ts.StructA{}, &ts.StructB{}, ts.StructA{}},
-		wantPanic: "invalid struct type",
-	}, {
-		label:     "Comparer",
-		fnc:       Comparer,
-		args:      []interface{}{5},
-		wantPanic: "invalid comparer function",
-	}, {
-		label: "Comparer",
-		fnc:   Comparer,
-		args:  []interface{}{func(x, y interface{}) bool { return true }},
-	}, {
-		label: "Comparer",
-		fnc:   Comparer,
-		args:  []interface{}{func(x, y io.Reader) bool { return true }},
-	}, {
-		label:     "Comparer",
-		fnc:       Comparer,
-		args:      []interface{}{func(x, y io.Reader) myBool { return true }},
-		wantPanic: "invalid comparer function",
-	}, {
-		label:     "Comparer",
-		fnc:       Comparer,
-		args:      []interface{}{func(x string, y interface{}) bool { return true }},
-		wantPanic: "invalid comparer function",
-	}, {
-		label:     "Comparer",
-		fnc:       Comparer,
-		args:      []interface{}{(func(int, int) bool)(nil)},
-		wantPanic: "invalid comparer function",
-	}, {
-		label:     "Transformer",
-		fnc:       Transformer,
-		args:      []interface{}{"", 0},
-		wantPanic: "invalid transformer function",
-	}, {
-		label: "Transformer",
-		fnc:   Transformer,
-		args:  []interface{}{"", func(int) int { return 0 }},
-	}, {
-		label: "Transformer",
-		fnc:   Transformer,
-		args:  []interface{}{"", func(bool) bool { return true }},
-	}, {
-		label: "Transformer",
-		fnc:   Transformer,
-		args:  []interface{}{"", func(int) bool { return true }},
-	}, {
-		label:     "Transformer",
-		fnc:       Transformer,
-		args:      []interface{}{"", func(int, int) bool { return true }},
-		wantPanic: "invalid transformer function",
-	}, {
-		label:     "Transformer",
-		fnc:       Transformer,
-		args:      []interface{}{"", (func(int) uint)(nil)},
-		wantPanic: "invalid transformer function",
-	}, {
-		label: "Transformer",
-		fnc:   Transformer,
-		args:  []interface{}{"Func", func(Path) Path { return nil }},
-	}, {
-		label: "Transformer",
-		fnc:   Transformer,
-		args:  []interface{}{"世界", func(int) bool { return true }},
-	}, {
-		label:     "Transformer",
-		fnc:       Transformer,
-		args:      []interface{}{"/*", func(int) bool { return true }},
-		wantPanic: "invalid name",
-	}, {
-		label:     "Transformer",
-		fnc:       Transformer,
-		args:      []interface{}{"_", func(int) bool { return true }},
-		wantPanic: "invalid name",
-	}, {
-		label:     "FilterPath",
-		fnc:       FilterPath,
-		args:      []interface{}{(func(Path) bool)(nil), Ignore()},
-		wantPanic: "invalid path filter function",
-	}, {
-		label: "FilterPath",
-		fnc:   FilterPath,
-		args:  []interface{}{func(Path) bool { return true }, Ignore()},
-	}, {
-		label:     "FilterPath",
-		fnc:       FilterPath,
-		args:      []interface{}{func(Path) bool { return true }, &defaultReporter{}},
-		wantPanic: "invalid option type",
-	}, {
-		label: "FilterPath",
-		fnc:   FilterPath,
-		args:  []interface{}{func(Path) bool { return true }, Options{Ignore(), Ignore()}},
-	}, {
-		label:     "FilterPath",
-		fnc:       FilterPath,
-		args:      []interface{}{func(Path) bool { return true }, Options{Ignore(), &defaultReporter{}}},
-		wantPanic: "invalid option type",
-	}, {
-		label:     "FilterValues",
-		fnc:       FilterValues,
-		args:      []interface{}{0, Ignore()},
-		wantPanic: "invalid values filter function",
-	}, {
-		label: "FilterValues",
-		fnc:   FilterValues,
-		args:  []interface{}{func(x, y int) bool { return true }, Ignore()},
-	}, {
-		label: "FilterValues",
-		fnc:   FilterValues,
-		args:  []interface{}{func(x, y interface{}) bool { return true }, Ignore()},
-	}, {
-		label:     "FilterValues",
-		fnc:       FilterValues,
-		args:      []interface{}{func(x, y interface{}) myBool { return true }, Ignore()},
-		wantPanic: "invalid values filter function",
-	}, {
-		label:     "FilterValues",
-		fnc:       FilterValues,
-		args:      []interface{}{func(x io.Reader, y interface{}) bool { return true }, Ignore()},
-		wantPanic: "invalid values filter function",
-	}, {
-		label:     "FilterValues",
-		fnc:       FilterValues,
-		args:      []interface{}{(func(int, int) bool)(nil), Ignore()},
-		wantPanic: "invalid values filter function",
-	}, {
-		label:     "FilterValues",
-		fnc:       FilterValues,
-		args:      []interface{}{func(int, int) bool { return true }, &defaultReporter{}},
-		wantPanic: "invalid option type",
-	}, {
-		label: "FilterValues",
-		fnc:   FilterValues,
-		args:  []interface{}{func(int, int) bool { return true }, Options{Ignore(), Ignore()}},
-	}, {
-		label:     "FilterValues",
-		fnc:       FilterValues,
-		args:      []interface{}{func(int, int) bool { return true }, Options{Ignore(), &defaultReporter{}}},
-		wantPanic: "invalid option type",
-	}}
-
-	for _, tt := range tests {
-		tRun(t, tt.label, func(t *testing.T) {
-			var gotPanic string
-			func() {
-				defer func() {
-					if ex := recover(); ex != nil {
-						if s, ok := ex.(string); ok {
-							gotPanic = s
-						} else {
-							panic(ex)
-						}
-					}
-				}()
-				var vargs []reflect.Value
-				for _, arg := range tt.args {
-					vargs = append(vargs, reflect.ValueOf(arg))
-				}
-				reflect.ValueOf(tt.fnc).Call(vargs)
-			}()
-			if tt.wantPanic == "" {
-				if gotPanic != "" {
-					t.Fatalf("unexpected panic message: %s", gotPanic)
-				}
-			} else {
-				if !strings.Contains(gotPanic, tt.wantPanic) {
-					t.Fatalf("panic message:\ngot:  %s\nwant: %s", gotPanic, tt.wantPanic)
-				}
-			}
-		})
-	}
-}
-
-// TODO: Delete this hack when we drop Go1.6 support.
-func tRun(t *testing.T, name string, f func(t *testing.T)) {
-	type runner interface {
-		Run(string, func(t *testing.T)) bool
-	}
-	var ti interface{} = t
-	if r, ok := ti.(runner); ok {
-		r.Run(name, f)
-	} else {
-		t.Logf("Test: %s", name)
-		f(t)
-	}
-}
diff --git a/vendor/github.com/pkg/errors/bench_test.go b/vendor/github.com/pkg/errors/bench_test.go
deleted file mode 100644
index 0416a3c..0000000
--- a/vendor/github.com/pkg/errors/bench_test.go
+++ /dev/null
@@ -1,59 +0,0 @@
-// +build go1.7
-
-package errors
-
-import (
-	"fmt"
-	"testing"
-
-	stderrors "errors"
-)
-
-func noErrors(at, depth int) error {
-	if at >= depth {
-		return stderrors.New("no error")
-	}
-	return noErrors(at+1, depth)
-}
-func yesErrors(at, depth int) error {
-	if at >= depth {
-		return New("ye error")
-	}
-	return yesErrors(at+1, depth)
-}
-
-func BenchmarkErrors(b *testing.B) {
-	var toperr error
-	type run struct {
-		stack int
-		std   bool
-	}
-	runs := []run{
-		{10, false},
-		{10, true},
-		{100, false},
-		{100, true},
-		{1000, false},
-		{1000, true},
-	}
-	for _, r := range runs {
-		part := "pkg/errors"
-		if r.std {
-			part = "errors"
-		}
-		name := fmt.Sprintf("%s-stack-%d", part, r.stack)
-		b.Run(name, func(b *testing.B) {
-			var err error
-			f := yesErrors
-			if r.std {
-				f = noErrors
-			}
-			b.ReportAllocs()
-			for i := 0; i < b.N; i++ {
-				err = f(0, r.stack)
-			}
-			b.StopTimer()
-			toperr = err
-		})
-	}
-}
diff --git a/vendor/github.com/pkg/errors/errors_test.go b/vendor/github.com/pkg/errors/errors_test.go
deleted file mode 100644
index 1d8c635..0000000
--- a/vendor/github.com/pkg/errors/errors_test.go
+++ /dev/null
@@ -1,226 +0,0 @@
-package errors
-
-import (
-	"errors"
-	"fmt"
-	"io"
-	"reflect"
-	"testing"
-)
-
-func TestNew(t *testing.T) {
-	tests := []struct {
-		err  string
-		want error
-	}{
-		{"", fmt.Errorf("")},
-		{"foo", fmt.Errorf("foo")},
-		{"foo", New("foo")},
-		{"string with format specifiers: %v", errors.New("string with format specifiers: %v")},
-	}
-
-	for _, tt := range tests {
-		got := New(tt.err)
-		if got.Error() != tt.want.Error() {
-			t.Errorf("New.Error(): got: %q, want %q", got, tt.want)
-		}
-	}
-}
-
-func TestWrapNil(t *testing.T) {
-	got := Wrap(nil, "no error")
-	if got != nil {
-		t.Errorf("Wrap(nil, \"no error\"): got %#v, expected nil", got)
-	}
-}
-
-func TestWrap(t *testing.T) {
-	tests := []struct {
-		err     error
-		message string
-		want    string
-	}{
-		{io.EOF, "read error", "read error: EOF"},
-		{Wrap(io.EOF, "read error"), "client error", "client error: read error: EOF"},
-	}
-
-	for _, tt := range tests {
-		got := Wrap(tt.err, tt.message).Error()
-		if got != tt.want {
-			t.Errorf("Wrap(%v, %q): got: %v, want %v", tt.err, tt.message, got, tt.want)
-		}
-	}
-}
-
-type nilError struct{}
-
-func (nilError) Error() string { return "nil error" }
-
-func TestCause(t *testing.T) {
-	x := New("error")
-	tests := []struct {
-		err  error
-		want error
-	}{{
-		// nil error is nil
-		err:  nil,
-		want: nil,
-	}, {
-		// explicit nil error is nil
-		err:  (error)(nil),
-		want: nil,
-	}, {
-		// typed nil is nil
-		err:  (*nilError)(nil),
-		want: (*nilError)(nil),
-	}, {
-		// uncaused error is unaffected
-		err:  io.EOF,
-		want: io.EOF,
-	}, {
-		// caused error returns cause
-		err:  Wrap(io.EOF, "ignored"),
-		want: io.EOF,
-	}, {
-		err:  x, // return from errors.New
-		want: x,
-	}, {
-		WithMessage(nil, "whoops"),
-		nil,
-	}, {
-		WithMessage(io.EOF, "whoops"),
-		io.EOF,
-	}, {
-		WithStack(nil),
-		nil,
-	}, {
-		WithStack(io.EOF),
-		io.EOF,
-	}}
-
-	for i, tt := range tests {
-		got := Cause(tt.err)
-		if !reflect.DeepEqual(got, tt.want) {
-			t.Errorf("test %d: got %#v, want %#v", i+1, got, tt.want)
-		}
-	}
-}
-
-func TestWrapfNil(t *testing.T) {
-	got := Wrapf(nil, "no error")
-	if got != nil {
-		t.Errorf("Wrapf(nil, \"no error\"): got %#v, expected nil", got)
-	}
-}
-
-func TestWrapf(t *testing.T) {
-	tests := []struct {
-		err     error
-		message string
-		want    string
-	}{
-		{io.EOF, "read error", "read error: EOF"},
-		{Wrapf(io.EOF, "read error without format specifiers"), "client error", "client error: read error without format specifiers: EOF"},
-		{Wrapf(io.EOF, "read error with %d format specifier", 1), "client error", "client error: read error with 1 format specifier: EOF"},
-	}
-
-	for _, tt := range tests {
-		got := Wrapf(tt.err, tt.message).Error()
-		if got != tt.want {
-			t.Errorf("Wrapf(%v, %q): got: %v, want %v", tt.err, tt.message, got, tt.want)
-		}
-	}
-}
-
-func TestErrorf(t *testing.T) {
-	tests := []struct {
-		err  error
-		want string
-	}{
-		{Errorf("read error without format specifiers"), "read error without format specifiers"},
-		{Errorf("read error with %d format specifier", 1), "read error with 1 format specifier"},
-	}
-
-	for _, tt := range tests {
-		got := tt.err.Error()
-		if got != tt.want {
-			t.Errorf("Errorf(%v): got: %q, want %q", tt.err, got, tt.want)
-		}
-	}
-}
-
-func TestWithStackNil(t *testing.T) {
-	got := WithStack(nil)
-	if got != nil {
-		t.Errorf("WithStack(nil): got %#v, expected nil", got)
-	}
-}
-
-func TestWithStack(t *testing.T) {
-	tests := []struct {
-		err  error
-		want string
-	}{
-		{io.EOF, "EOF"},
-		{WithStack(io.EOF), "EOF"},
-	}
-
-	for _, tt := range tests {
-		got := WithStack(tt.err).Error()
-		if got != tt.want {
-			t.Errorf("WithStack(%v): got: %v, want %v", tt.err, got, tt.want)
-		}
-	}
-}
-
-func TestWithMessageNil(t *testing.T) {
-	got := WithMessage(nil, "no error")
-	if got != nil {
-		t.Errorf("WithMessage(nil, \"no error\"): got %#v, expected nil", got)
-	}
-}
-
-func TestWithMessage(t *testing.T) {
-	tests := []struct {
-		err     error
-		message string
-		want    string
-	}{
-		{io.EOF, "read error", "read error: EOF"},
-		{WithMessage(io.EOF, "read error"), "client error", "client error: read error: EOF"},
-	}
-
-	for _, tt := range tests {
-		got := WithMessage(tt.err, tt.message).Error()
-		if got != tt.want {
-			t.Errorf("WithMessage(%v, %q): got: %q, want %q", tt.err, tt.message, got, tt.want)
-		}
-	}
-
-}
-
-// errors.New, etc values are not expected to be compared by value
-// but the change in errors#27 made them incomparable. Assert that
-// various kinds of errors have a functional equality operator, even
-// if the result of that equality is always false.
-func TestErrorEquality(t *testing.T) {
-	vals := []error{
-		nil,
-		io.EOF,
-		errors.New("EOF"),
-		New("EOF"),
-		Errorf("EOF"),
-		Wrap(io.EOF, "EOF"),
-		Wrapf(io.EOF, "EOF%d", 2),
-		WithMessage(nil, "whoops"),
-		WithMessage(io.EOF, "whoops"),
-		WithStack(io.EOF),
-		WithStack(nil),
-	}
-
-	for i := range vals {
-		for j := range vals {
-			_ = vals[i] == vals[j] // mustn't panic
-		}
-	}
-}
diff --git a/vendor/github.com/pkg/errors/example_test.go b/vendor/github.com/pkg/errors/example_test.go
deleted file mode 100644
index c1fc13e..0000000
--- a/vendor/github.com/pkg/errors/example_test.go
+++ /dev/null
@@ -1,205 +0,0 @@
-package errors_test
-
-import (
-	"fmt"
-
-	"github.com/pkg/errors"
-)
-
-func ExampleNew() {
-	err := errors.New("whoops")
-	fmt.Println(err)
-
-	// Output: whoops
-}
-
-func ExampleNew_printf() {
-	err := errors.New("whoops")
-	fmt.Printf("%+v", err)
-
-	// Example output:
-	// whoops
-	// github.com/pkg/errors_test.ExampleNew_printf
-	//         /home/dfc/src/github.com/pkg/errors/example_test.go:17
-	// testing.runExample
-	//         /home/dfc/go/src/testing/example.go:114
-	// testing.RunExamples
-	//         /home/dfc/go/src/testing/example.go:38
-	// testing.(*M).Run
-	//         /home/dfc/go/src/testing/testing.go:744
-	// main.main
-	//         /github.com/pkg/errors/_test/_testmain.go:106
-	// runtime.main
-	//         /home/dfc/go/src/runtime/proc.go:183
-	// runtime.goexit
-	//         /home/dfc/go/src/runtime/asm_amd64.s:2059
-}
-
-func ExampleWithMessage() {
-	cause := errors.New("whoops")
-	err := errors.WithMessage(cause, "oh noes")
-	fmt.Println(err)
-
-	// Output: oh noes: whoops
-}
-
-func ExampleWithStack() {
-	cause := errors.New("whoops")
-	err := errors.WithStack(cause)
-	fmt.Println(err)
-
-	// Output: whoops
-}
-
-func ExampleWithStack_printf() {
-	cause := errors.New("whoops")
-	err := errors.WithStack(cause)
-	fmt.Printf("%+v", err)
-
-	// Example Output:
-	// whoops
-	// github.com/pkg/errors_test.ExampleWithStack_printf
-	//         /home/fabstu/go/src/github.com/pkg/errors/example_test.go:55
-	// testing.runExample
-	//         /usr/lib/go/src/testing/example.go:114
-	// testing.RunExamples
-	//         /usr/lib/go/src/testing/example.go:38
-	// testing.(*M).Run
-	//         /usr/lib/go/src/testing/testing.go:744
-	// main.main
-	//         github.com/pkg/errors/_test/_testmain.go:106
-	// runtime.main
-	//         /usr/lib/go/src/runtime/proc.go:183
-	// runtime.goexit
-	//         /usr/lib/go/src/runtime/asm_amd64.s:2086
-	// github.com/pkg/errors_test.ExampleWithStack_printf
-	//         /home/fabstu/go/src/github.com/pkg/errors/example_test.go:56
-	// testing.runExample
-	//         /usr/lib/go/src/testing/example.go:114
-	// testing.RunExamples
-	//         /usr/lib/go/src/testing/example.go:38
-	// testing.(*M).Run
-	//         /usr/lib/go/src/testing/testing.go:744
-	// main.main
-	//         github.com/pkg/errors/_test/_testmain.go:106
-	// runtime.main
-	//         /usr/lib/go/src/runtime/proc.go:183
-	// runtime.goexit
-	//         /usr/lib/go/src/runtime/asm_amd64.s:2086
-}
-
-func ExampleWrap() {
-	cause := errors.New("whoops")
-	err := errors.Wrap(cause, "oh noes")
-	fmt.Println(err)
-
-	// Output: oh noes: whoops
-}
-
-func fn() error {
-	e1 := errors.New("error")
-	e2 := errors.Wrap(e1, "inner")
-	e3 := errors.Wrap(e2, "middle")
-	return errors.Wrap(e3, "outer")
-}
-
-func ExampleCause() {
-	err := fn()
-	fmt.Println(err)
-	fmt.Println(errors.Cause(err))
-
-	// Output: outer: middle: inner: error
-	// error
-}
-
-func ExampleWrap_extended() {
-	err := fn()
-	fmt.Printf("%+v\n", err)
-
-	// Example output:
-	// error
-	// github.com/pkg/errors_test.fn
-	//         /home/dfc/src/github.com/pkg/errors/example_test.go:47
-	// github.com/pkg/errors_test.ExampleCause_printf
-	//         /home/dfc/src/github.com/pkg/errors/example_test.go:63
-	// testing.runExample
-	//         /home/dfc/go/src/testing/example.go:114
-	// testing.RunExamples
-	//         /home/dfc/go/src/testing/example.go:38
-	// testing.(*M).Run
-	//         /home/dfc/go/src/testing/testing.go:744
-	// main.main
-	//         /github.com/pkg/errors/_test/_testmain.go:104
-	// runtime.main
-	//         /home/dfc/go/src/runtime/proc.go:183
-	// runtime.goexit
-	//         /home/dfc/go/src/runtime/asm_amd64.s:2059
-	// github.com/pkg/errors_test.fn
-	// 	  /home/dfc/src/github.com/pkg/errors/example_test.go:48: inner
-	// github.com/pkg/errors_test.fn
-	//        /home/dfc/src/github.com/pkg/errors/example_test.go:49: middle
-	// github.com/pkg/errors_test.fn
-	//      /home/dfc/src/github.com/pkg/errors/example_test.go:50: outer
-}
-
-func ExampleWrapf() {
-	cause := errors.New("whoops")
-	err := errors.Wrapf(cause, "oh noes #%d", 2)
-	fmt.Println(err)
-
-	// Output: oh noes #2: whoops
-}
-
-func ExampleErrorf_extended() {
-	err := errors.Errorf("whoops: %s", "foo")
-	fmt.Printf("%+v", err)
-
-	// Example output:
-	// whoops: foo
-	// github.com/pkg/errors_test.ExampleErrorf
-	//         /home/dfc/src/github.com/pkg/errors/example_test.go:101
-	// testing.runExample
-	//         /home/dfc/go/src/testing/example.go:114
-	// testing.RunExamples
-	//         /home/dfc/go/src/testing/example.go:38
-	// testing.(*M).Run
-	//         /home/dfc/go/src/testing/testing.go:744
-	// main.main
-	//         /github.com/pkg/errors/_test/_testmain.go:102
-	// runtime.main
-	//         /home/dfc/go/src/runtime/proc.go:183
-	// runtime.goexit
-	//         /home/dfc/go/src/runtime/asm_amd64.s:2059
-}
-
-func Example_stackTrace() {
-	type stackTracer interface {
-		StackTrace() errors.StackTrace
-	}
-
-	err, ok := errors.Cause(fn()).(stackTracer)
-	if !ok {
-		panic("oops, err does not implement stackTracer")
-	}
-
-	st := err.StackTrace()
-	fmt.Printf("%+v", st[0:2]) // top two frames
-
-	// Example output:
-	// github.com/pkg/errors_test.fn
-	//	/home/dfc/src/github.com/pkg/errors/example_test.go:47
-	// github.com/pkg/errors_test.Example_stackTrace
-	//	/home/dfc/src/github.com/pkg/errors/example_test.go:127
-}
-
-func ExampleCause_printf() {
-	err := errors.Wrap(func() error {
-		return func() error {
-			return errors.Errorf("hello %s", fmt.Sprintf("world"))
-		}()
-	}(), "failed")
-
-	fmt.Printf("%v", err)
-
-	// Output: failed: hello world
-}
diff --git a/vendor/github.com/pkg/errors/format_test.go b/vendor/github.com/pkg/errors/format_test.go
deleted file mode 100644
index 15fd7d8..0000000
--- a/vendor/github.com/pkg/errors/format_test.go
+++ /dev/null
@@ -1,535 +0,0 @@
-package errors
-
-import (
-	"errors"
-	"fmt"
-	"io"
-	"regexp"
-	"strings"
-	"testing"
-)
-
-func TestFormatNew(t *testing.T) {
-	tests := []struct {
-		error
-		format string
-		want   string
-	}{{
-		New("error"),
-		"%s",
-		"error",
-	}, {
-		New("error"),
-		"%v",
-		"error",
-	}, {
-		New("error"),
-		"%+v",
-		"error\n" +
-			"github.com/pkg/errors.TestFormatNew\n" +
-			"\t.+/github.com/pkg/errors/format_test.go:26",
-	}, {
-		New("error"),
-		"%q",
-		`"error"`,
-	}}
-
-	for i, tt := range tests {
-		testFormatRegexp(t, i, tt.error, tt.format, tt.want)
-	}
-}
-
-func TestFormatErrorf(t *testing.T) {
-	tests := []struct {
-		error
-		format string
-		want   string
-	}{{
-		Errorf("%s", "error"),
-		"%s",
-		"error",
-	}, {
-		Errorf("%s", "error"),
-		"%v",
-		"error",
-	}, {
-		Errorf("%s", "error"),
-		"%+v",
-		"error\n" +
-			"github.com/pkg/errors.TestFormatErrorf\n" +
-			"\t.+/github.com/pkg/errors/format_test.go:56",
-	}}
-
-	for i, tt := range tests {
-		testFormatRegexp(t, i, tt.error, tt.format, tt.want)
-	}
-}
-
-func TestFormatWrap(t *testing.T) {
-	tests := []struct {
-		error
-		format string
-		want   string
-	}{{
-		Wrap(New("error"), "error2"),
-		"%s",
-		"error2: error",
-	}, {
-		Wrap(New("error"), "error2"),
-		"%v",
-		"error2: error",
-	}, {
-		Wrap(New("error"), "error2"),
-		"%+v",
-		"error\n" +
-			"github.com/pkg/errors.TestFormatWrap\n" +
-			"\t.+/github.com/pkg/errors/format_test.go:82",
-	}, {
-		Wrap(io.EOF, "error"),
-		"%s",
-		"error: EOF",
-	}, {
-		Wrap(io.EOF, "error"),
-		"%v",
-		"error: EOF",
-	}, {
-		Wrap(io.EOF, "error"),
-		"%+v",
-		"EOF\n" +
-			"error\n" +
-			"github.com/pkg/errors.TestFormatWrap\n" +
-			"\t.+/github.com/pkg/errors/format_test.go:96",
-	}, {
-		Wrap(Wrap(io.EOF, "error1"), "error2"),
-		"%+v",
-		"EOF\n" +
-			"error1\n" +
-			"github.com/pkg/errors.TestFormatWrap\n" +
-			"\t.+/github.com/pkg/errors/format_test.go:103\n",
-	}, {
-		Wrap(New("error with space"), "context"),
-		"%q",
-		`"context: error with space"`,
-	}}
-
-	for i, tt := range tests {
-		testFormatRegexp(t, i, tt.error, tt.format, tt.want)
-	}
-}
-
-func TestFormatWrapf(t *testing.T) {
-	tests := []struct {
-		error
-		format string
-		want   string
-	}{{
-		Wrapf(io.EOF, "error%d", 2),
-		"%s",
-		"error2: EOF",
-	}, {
-		Wrapf(io.EOF, "error%d", 2),
-		"%v",
-		"error2: EOF",
-	}, {
-		Wrapf(io.EOF, "error%d", 2),
-		"%+v",
-		"EOF\n" +
-			"error2\n" +
-			"github.com/pkg/errors.TestFormatWrapf\n" +
-			"\t.+/github.com/pkg/errors/format_test.go:134",
-	}, {
-		Wrapf(New("error"), "error%d", 2),
-		"%s",
-		"error2: error",
-	}, {
-		Wrapf(New("error"), "error%d", 2),
-		"%v",
-		"error2: error",
-	}, {
-		Wrapf(New("error"), "error%d", 2),
-		"%+v",
-		"error\n" +
-			"github.com/pkg/errors.TestFormatWrapf\n" +
-			"\t.+/github.com/pkg/errors/format_test.go:149",
-	}}
-
-	for i, tt := range tests {
-		testFormatRegexp(t, i, tt.error, tt.format, tt.want)
-	}
-}
-
-func TestFormatWithStack(t *testing.T) {
-	tests := []struct {
-		error
-		format string
-		want   []string
-	}{{
-		WithStack(io.EOF),
-		"%s",
-		[]string{"EOF"},
-	}, {
-		WithStack(io.EOF),
-		"%v",
-		[]string{"EOF"},
-	}, {
-		WithStack(io.EOF),
-		"%+v",
-		[]string{"EOF",
-			"github.com/pkg/errors.TestFormatWithStack\n" +
-				"\t.+/github.com/pkg/errors/format_test.go:175"},
-	}, {
-		WithStack(New("error")),
-		"%s",
-		[]string{"error"},
-	}, {
-		WithStack(New("error")),
-		"%v",
-		[]string{"error"},
-	}, {
-		WithStack(New("error")),
-		"%+v",
-		[]string{"error",
-			"github.com/pkg/errors.TestFormatWithStack\n" +
-				"\t.+/github.com/pkg/errors/format_test.go:189",
-			"github.com/pkg/errors.TestFormatWithStack\n" +
-				"\t.+/github.com/pkg/errors/format_test.go:189"},
-	}, {
-		WithStack(WithStack(io.EOF)),
-		"%+v",
-		[]string{"EOF",
-			"github.com/pkg/errors.TestFormatWithStack\n" +
-				"\t.+/github.com/pkg/errors/format_test.go:197",
-			"github.com/pkg/errors.TestFormatWithStack\n" +
-				"\t.+/github.com/pkg/errors/format_test.go:197"},
-	}, {
-		WithStack(WithStack(Wrapf(io.EOF, "message"))),
-		"%+v",
-		[]string{"EOF",
-			"message",
-			"github.com/pkg/errors.TestFormatWithStack\n" +
-				"\t.+/github.com/pkg/errors/format_test.go:205",
-			"github.com/pkg/errors.TestFormatWithStack\n" +
-				"\t.+/github.com/pkg/errors/format_test.go:205",
-			"github.com/pkg/errors.TestFormatWithStack\n" +
-				"\t.+/github.com/pkg/errors/format_test.go:205"},
-	}, {
-		WithStack(Errorf("error%d", 1)),
-		"%+v",
-		[]string{"error1",
-			"github.com/pkg/errors.TestFormatWithStack\n" +
-				"\t.+/github.com/pkg/errors/format_test.go:216",
-			"github.com/pkg/errors.TestFormatWithStack\n" +
-				"\t.+/github.com/pkg/errors/format_test.go:216"},
-	}}
-
-	for i, tt := range tests {
-		testFormatCompleteCompare(t, i, tt.error, tt.format, tt.want, true)
-	}
-}
-
-func TestFormatWithMessage(t *testing.T) {
-	tests := []struct {
-		error
-		format string
-		want   []string
-	}{{
-		WithMessage(New("error"), "error2"),
-		"%s",
-		[]string{"error2: error"},
-	}, {
-		WithMessage(New("error"), "error2"),
-		"%v",
-		[]string{"error2: error"},
-	}, {
-		WithMessage(New("error"), "error2"),
-		"%+v",
-		[]string{
-			"error",
-			"github.com/pkg/errors.TestFormatWithMessage\n" +
-				"\t.+/github.com/pkg/errors/format_test.go:244",
-			"error2"},
-	}, {
-		WithMessage(io.EOF, "addition1"),
-		"%s",
-		[]string{"addition1: EOF"},
-	}, {
-		WithMessage(io.EOF, "addition1"),
-		"%v",
-		[]string{"addition1: EOF"},
-	}, {
-		WithMessage(io.EOF, "addition1"),
-		"%+v",
-		[]string{"EOF", "addition1"},
-	}, {
-		WithMessage(WithMessage(io.EOF, "addition1"), "addition2"),
-		"%v",
-		[]string{"addition2: addition1: EOF"},
-	}, {
-		WithMessage(WithMessage(io.EOF, "addition1"), "addition2"),
-		"%+v",
-		[]string{"EOF", "addition1", "addition2"},
-	}, {
-		Wrap(WithMessage(io.EOF, "error1"), "error2"),
-		"%+v",
-		[]string{"EOF", "error1", "error2",
-			"github.com/pkg/errors.TestFormatWithMessage\n" +
-				"\t.+/github.com/pkg/errors/format_test.go:272"},
-	}, {
-		WithMessage(Errorf("error%d", 1), "error2"),
-		"%+v",
-		[]string{"error1",
-			"github.com/pkg/errors.TestFormatWithMessage\n" +
-				"\t.+/github.com/pkg/errors/format_test.go:278",
-			"error2"},
-	}, {
-		WithMessage(WithStack(io.EOF), "error"),
-		"%+v",
-		[]string{
-			"EOF",
-			"github.com/pkg/errors.TestFormatWithMessage\n" +
-				"\t.+/github.com/pkg/errors/format_test.go:285",
-			"error"},
-	}, {
-		WithMessage(Wrap(WithStack(io.EOF), "inside-error"), "outside-error"),
-		"%+v",
-		[]string{
-			"EOF",
-			"github.com/pkg/errors.TestFormatWithMessage\n" +
-				"\t.+/github.com/pkg/errors/format_test.go:293",
-			"inside-error",
-			"github.com/pkg/errors.TestFormatWithMessage\n" +
-				"\t.+/github.com/pkg/errors/format_test.go:293",
-			"outside-error"},
-	}}
-
-	for i, tt := range tests {
-		testFormatCompleteCompare(t, i, tt.error, tt.format, tt.want, true)
-	}
-}
-
-func TestFormatGeneric(t *testing.T) {
-	starts := []struct {
-		err  error
-		want []string
-	}{
-		{New("new-error"), []string{
-			"new-error",
-			"github.com/pkg/errors.TestFormatGeneric\n" +
-				"\t.+/github.com/pkg/errors/format_test.go:315"},
-		}, {Errorf("errorf-error"), []string{
-			"errorf-error",
-			"github.com/pkg/errors.TestFormatGeneric\n" +
-				"\t.+/github.com/pkg/errors/format_test.go:319"},
-		}, {errors.New("errors-new-error"), []string{
-			"errors-new-error"},
-		},
-	}
-
-	wrappers := []wrapper{
-		{
-			func(err error) error { return WithMessage(err, "with-message") },
-			[]string{"with-message"},
-		}, {
-			func(err error) error { return WithStack(err) },
-			[]string{
-				"github.com/pkg/errors.(func·002|TestFormatGeneric.func2)\n\t" +
-					".+/github.com/pkg/errors/format_test.go:333",
-			},
-		}, {
-			func(err error) error { return Wrap(err, "wrap-error") },
-			[]string{
-				"wrap-error",
-				"github.com/pkg/errors.(func·003|TestFormatGeneric.func3)\n\t" +
-					".+/github.com/pkg/errors/format_test.go:339",
-			},
-		}, {
-			func(err error) error { return Wrapf(err, "wrapf-error%d", 1) },
-			[]string{
-				"wrapf-error1",
-				"github.com/pkg/errors.(func·004|TestFormatGeneric.func4)\n\t" +
-					".+/github.com/pkg/errors/format_test.go:346",
-			},
-		},
-	}
-
-	for s := range starts {
-		err := starts[s].err
-		want := starts[s].want
-		testFormatCompleteCompare(t, s, err, "%+v", want, false)
-		testGenericRecursive(t, err, want, wrappers, 3)
-	}
-}
-
-func testFormatRegexp(t *testing.T, n int, arg interface{}, format, want string) {
-	got := fmt.Sprintf(format, arg)
-	gotLines := strings.SplitN(got, "\n", -1)
-	wantLines := strings.SplitN(want, "\n", -1)
-
-	if len(wantLines) > len(gotLines) {
-		t.Errorf("test %d: wantLines(%d) > gotLines(%d):\n got: %q\nwant: %q", n+1, len(wantLines), len(gotLines), got, want)
-		return
-	}
-
-	for i, w := range wantLines {
-		match, err := regexp.MatchString(w, gotLines[i])
-		if err != nil {
-			t.Fatal(err)
-		}
-		if !match {
-			t.Errorf("test %d: line %d: fmt.Sprintf(%q, err):\n got: %q\nwant: %q", n+1, i+1, format, got, want)
-		}
-	}
-}
-
-var stackLineR = regexp.MustCompile(`\.`)
-
-// parseBlocks parses input into a slice, where:
-//  - incase entry contains a newline, its a stacktrace
-//  - incase entry contains no newline, its a solo line.
-//
-// Detecting stack boundaries only works incase the WithStack-calls are
-// to be found on the same line, thats why it is optionally here.
-//
-// Example use:
-//
-// for _, e := range blocks {
-//   if strings.ContainsAny(e, "\n") {
-//     // Match as stack
-//   } else {
-//     // Match as line
-//   }
-// }
-//
-func parseBlocks(input string, detectStackboundaries bool) ([]string, error) {
-	var blocks []string
-
-	stack := ""
-	wasStack := false
-	lines := map[string]bool{} // already found lines
-
-	for _, l := range strings.Split(input, "\n") {
-		isStackLine := stackLineR.MatchString(l)
-
-		switch {
-		case !isStackLine && wasStack:
-			blocks = append(blocks, stack, l)
-			stack = ""
-			lines = map[string]bool{}
-		case isStackLine:
-			if wasStack {
-				// Detecting two stacks after another, possible cause lines match in
-				// our tests due to WithStack(WithStack(io.EOF)) on same line.
-				if detectStackboundaries {
-					if lines[l] {
-						if len(stack) == 0 {
-							return nil, errors.New("len of block must not be zero here")
-						}
-
-						blocks = append(blocks, stack)
-						stack = l
-						lines = map[string]bool{l: true}
-						continue
-					}
-				}
-
-				stack = stack + "\n" + l
-			} else {
-				stack = l
-			}
-			lines[l] = true
-		case !isStackLine && !wasStack:
-			blocks = append(blocks, l)
-		default:
-			return nil, errors.New("must not happen")
-		}
-
-		wasStack = isStackLine
-	}
-
-	// Use up stack
-	if stack != "" {
-		blocks = append(blocks, stack)
-	}
-	return blocks, nil
-}
-
-func testFormatCompleteCompare(t *testing.T, n int, arg interface{}, format string, want []string, detectStackBoundaries bool) {
-	gotStr := fmt.Sprintf(format, arg)
-
-	got, err := parseBlocks(gotStr, detectStackBoundaries)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	if len(got) != len(want) {
-		t.Fatalf("test %d: fmt.Sprintf(%s, err) -> wrong number of blocks: got(%d) want(%d)\n got: %s\nwant: %s\ngotStr: %q",
-			n+1, format, len(got), len(want), prettyBlocks(got), prettyBlocks(want), gotStr)
-	}
-
-	for i := range got {
-		if strings.ContainsAny(want[i], "\n") {
-			// Match as stack
-			match, err := regexp.MatchString(want[i], got[i])
-			if err != nil {
-				t.Fatal(err)
-			}
-			if !match {
-				t.Fatalf("test %d: block %d: fmt.Sprintf(%q, err):\ngot:\n%q\nwant:\n%q\nall-got:\n%s\nall-want:\n%s\n",
-					n+1, i+1, format, got[i], want[i], prettyBlocks(got), prettyBlocks(want))
-			}
-		} else {
-			// Match as message
-			if got[i] != want[i] {
-				t.Fatalf("test %d: fmt.Sprintf(%s, err) at block %d got != want:\n got: %q\nwant: %q", n+1, format, i+1, got[i], want[i])
-			}
-		}
-	}
-}
-
-type wrapper struct {
-	wrap func(err error) error
-	want []string
-}
-
-func prettyBlocks(blocks []string, prefix ...string) string {
-	var out []string
-
-	for _, b := range blocks {
-		out = append(out, fmt.Sprintf("%v", b))
-	}
-
-	return "   " + strings.Join(out, "\n   ")
-}
-
-func testGenericRecursive(t *testing.T, beforeErr error, beforeWant []string, list []wrapper, maxDepth int) {
-	if len(beforeWant) == 0 {
-		panic("beforeWant must not be empty")
-	}
-	for _, w := range list {
-		if len(w.want) == 0 {
-			panic("want must not be empty")
-		}
-
-		err := w.wrap(beforeErr)
-
-		// Copy required cause append(beforeWant, ..) modified beforeWant subtly.
-		beforeCopy := make([]string, len(beforeWant))
-		copy(beforeCopy, beforeWant)
-
-		beforeWant := beforeCopy
-		last := len(beforeWant) - 1
-		var want []string
-
-		// Merge two stacks behind each other.
-		if strings.ContainsAny(beforeWant[last], "\n") && strings.ContainsAny(w.want[0], "\n") {
-			want = append(beforeWant[:last], append([]string{beforeWant[last] + "((?s).*)" + w.want[0]}, w.want[1:]...)...)
-		} else {
-			want = append(beforeWant, w.want...)
-		}
-
-		testFormatCompleteCompare(t, maxDepth, err, "%+v", want, false)
-		if maxDepth > 0 {
-			testGenericRecursive(t, err, want, list, maxDepth-1)
-		}
-	}
-}
diff --git a/vendor/github.com/pkg/errors/stack_test.go b/vendor/github.com/pkg/errors/stack_test.go
deleted file mode 100644
index 510c27a..0000000
--- a/vendor/github.com/pkg/errors/stack_test.go
+++ /dev/null
@@ -1,292 +0,0 @@
-package errors
-
-import (
-	"fmt"
-	"runtime"
-	"testing"
-)
-
-var initpc, _, _, _ = runtime.Caller(0)
-
-func TestFrameLine(t *testing.T) {
-	var tests = []struct {
-		Frame
-		want int
-	}{{
-		Frame(initpc),
-		9,
-	}, {
-		func() Frame {
-			var pc, _, _, _ = runtime.Caller(0)
-			return Frame(pc)
-		}(),
-		20,
-	}, {
-		func() Frame {
-			var pc, _, _, _ = runtime.Caller(1)
-			return Frame(pc)
-		}(),
-		28,
-	}, {
-		Frame(0), // invalid PC
-		0,
-	}}
-
-	for _, tt := range tests {
-		got := tt.Frame.line()
-		want := tt.want
-		if want != got {
-			t.Errorf("Frame(%v): want: %v, got: %v", uintptr(tt.Frame), want, got)
-		}
-	}
-}
-
-type X struct{}
-
-func (x X) val() Frame {
-	var pc, _, _, _ = runtime.Caller(0)
-	return Frame(pc)
-}
-
-func (x *X) ptr() Frame {
-	var pc, _, _, _ = runtime.Caller(0)
-	return Frame(pc)
-}
-
-func TestFrameFormat(t *testing.T) {
-	var tests = []struct {
-		Frame
-		format string
-		want   string
-	}{{
-		Frame(initpc),
-		"%s",
-		"stack_test.go",
-	}, {
-		Frame(initpc),
-		"%+s",
-		"github.com/pkg/errors.init\n" +
-			"\t.+/github.com/pkg/errors/stack_test.go",
-	}, {
-		Frame(0),
-		"%s",
-		"unknown",
-	}, {
-		Frame(0),
-		"%+s",
-		"unknown",
-	}, {
-		Frame(initpc),
-		"%d",
-		"9",
-	}, {
-		Frame(0),
-		"%d",
-		"0",
-	}, {
-		Frame(initpc),
-		"%n",
-		"init",
-	}, {
-		func() Frame {
-			var x X
-			return x.ptr()
-		}(),
-		"%n",
-		`\(\*X\).ptr`,
-	}, {
-		func() Frame {
-			var x X
-			return x.val()
-		}(),
-		"%n",
-		"X.val",
-	}, {
-		Frame(0),
-		"%n",
-		"",
-	}, {
-		Frame(initpc),
-		"%v",
-		"stack_test.go:9",
-	}, {
-		Frame(initpc),
-		"%+v",
-		"github.com/pkg/errors.init\n" +
-			"\t.+/github.com/pkg/errors/stack_test.go:9",
-	}, {
-		Frame(0),
-		"%v",
-		"unknown:0",
-	}}
-
-	for i, tt := range tests {
-		testFormatRegexp(t, i, tt.Frame, tt.format, tt.want)
-	}
-}
-
-func TestFuncname(t *testing.T) {
-	tests := []struct {
-		name, want string
-	}{
-		{"", ""},
-		{"runtime.main", "main"},
-		{"github.com/pkg/errors.funcname", "funcname"},
-		{"funcname", "funcname"},
-		{"io.copyBuffer", "copyBuffer"},
-		{"main.(*R).Write", "(*R).Write"},
-	}
-
-	for _, tt := range tests {
-		got := funcname(tt.name)
-		want := tt.want
-		if got != want {
-			t.Errorf("funcname(%q): want: %q, got %q", tt.name, want, got)
-		}
-	}
-}
-
-func TestTrimGOPATH(t *testing.T) {
-	var tests = []struct {
-		Frame
-		want string
-	}{{
-		Frame(initpc),
-		"github.com/pkg/errors/stack_test.go",
-	}}
-
-	for i, tt := range tests {
-		pc := tt.Frame.pc()
-		fn := runtime.FuncForPC(pc)
-		file, _ := fn.FileLine(pc)
-		got := trimGOPATH(fn.Name(), file)
-		testFormatRegexp(t, i, got, "%s", tt.want)
-	}
-}
-
-func TestStackTrace(t *testing.T) {
-	tests := []struct {
-		err  error
-		want []string
-	}{{
-		New("ooh"), []string{
-			"github.com/pkg/errors.TestStackTrace\n" +
-				"\t.+/github.com/pkg/errors/stack_test.go:172",
-		},
-	}, {
-		Wrap(New("ooh"), "ahh"), []string{
-			"github.com/pkg/errors.TestStackTrace\n" +
-				"\t.+/github.com/pkg/errors/stack_test.go:177", // this is the stack of Wrap, not New
-		},
-	}, {
-		Cause(Wrap(New("ooh"), "ahh")), []string{
-			"github.com/pkg/errors.TestStackTrace\n" +
-				"\t.+/github.com/pkg/errors/stack_test.go:182", // this is the stack of New
-		},
-	}, {
-		func() error { return New("ooh") }(), []string{
-			`github.com/pkg/errors.(func·009|TestStackTrace.func1)` +
-				"\n\t.+/github.com/pkg/errors/stack_test.go:187", // this is the stack of New
-			"github.com/pkg/errors.TestStackTrace\n" +
-				"\t.+/github.com/pkg/errors/stack_test.go:187", // this is the stack of New's caller
-		},
-	}, {
-		Cause(func() error {
-			return func() error {
-				return Errorf("hello %s", fmt.Sprintf("world"))
-			}()
-		}()), []string{
-			`github.com/pkg/errors.(func·010|TestStackTrace.func2.1)` +
-				"\n\t.+/github.com/pkg/errors/stack_test.go:196", // this is the stack of Errorf
-			`github.com/pkg/errors.(func·011|TestStackTrace.func2)` +
-				"\n\t.+/github.com/pkg/errors/stack_test.go:197", // this is the stack of Errorf's caller
-			"github.com/pkg/errors.TestStackTrace\n" +
-				"\t.+/github.com/pkg/errors/stack_test.go:198", // this is the stack of Errorf's caller's caller
-		},
-	}}
-	for i, tt := range tests {
-		x, ok := tt.err.(interface {
-			StackTrace() StackTrace
-		})
-		if !ok {
-			t.Errorf("expected %#v to implement StackTrace() StackTrace", tt.err)
-			continue
-		}
-		st := x.StackTrace()
-		for j, want := range tt.want {
-			testFormatRegexp(t, i, st[j], "%+v", want)
-		}
-	}
-}
-
-func stackTrace() StackTrace {
-	const depth = 8
-	var pcs [depth]uintptr
-	n := runtime.Callers(1, pcs[:])
-	var st stack = pcs[0:n]
-	return st.StackTrace()
-}
-
-func TestStackTraceFormat(t *testing.T) {
-	tests := []struct {
-		StackTrace
-		format string
-		want   string
-	}{{
-		nil,
-		"%s",
-		`\[\]`,
-	}, {
-		nil,
-		"%v",
-		`\[\]`,
-	}, {
-		nil,
-		"%+v",
-		"",
-	}, {
-		nil,
-		"%#v",
-		`\[\]errors.Frame\(nil\)`,
-	}, {
-		make(StackTrace, 0),
-		"%s",
-		`\[\]`,
-	}, {
-		make(StackTrace, 0),
-		"%v",
-		`\[\]`,
-	}, {
-		make(StackTrace, 0),
-		"%+v",
-		"",
-	}, {
-		make(StackTrace, 0),
-		"%#v",
-		`\[\]errors.Frame{}`,
-	}, {
-		stackTrace()[:2],
-		"%s",
-		`\[stack_test.go stack_test.go\]`,
-	}, {
-		stackTrace()[:2],
-		"%v",
-		`\[stack_test.go:225 stack_test.go:272\]`,
-	}, {
-		stackTrace()[:2],
-		"%+v",
-		"\n" +
-			"github.com/pkg/errors.stackTrace\n" +
-			"\t.+/github.com/pkg/errors/stack_test.go:225\n" +
-			"github.com/pkg/errors.TestStackTraceFormat\n" +
-			"\t.+/github.com/pkg/errors/stack_test.go:276",
-	}, {
-		stackTrace()[:2],
-		"%#v",
-		`\[\]errors.Frame{stack_test.go:225, stack_test.go:284}`,
-	}}
-
-	for i, tt := range tests {
-		testFormatRegexp(t, i, tt.StackTrace, tt.format, tt.want)
-	}
-}