diff --git a/vendor/gotest.tools/internal/difflib/LICENSE b/vendor/gotest.tools/internal/difflib/LICENSE
new file mode 100644
index 0000000..c67dad6
--- /dev/null
+++ b/vendor/gotest.tools/internal/difflib/LICENSE
@@ -0,0 +1,27 @@
+Copyright (c) 2013, Patrick Mezard
+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.
+    The names of its contributors may not 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
+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/gotest.tools/internal/difflib/difflib.go b/vendor/gotest.tools/internal/difflib/difflib.go
new file mode 100644
index 0000000..b6f486b
--- /dev/null
+++ b/vendor/gotest.tools/internal/difflib/difflib.go
@@ -0,0 +1,423 @@
+/*Package difflib is a partial port of Python difflib module.
+
+Original source: https://github.com/pmezard/go-difflib
+
+This file is trimmed to only the parts used by this repository.
+*/
+package difflib // import "gotest.tools/internal/difflib"
+
+func min(a, b int) int {
+	if a < b {
+		return a
+	}
+	return b
+}
+
+func max(a, b int) int {
+	if a > b {
+		return a
+	}
+	return b
+}
+
+// Match stores line numbers of size of match
+type Match struct {
+	A    int
+	B    int
+	Size int
+}
+
+// OpCode identifies the type of diff
+type OpCode struct {
+	Tag byte
+	I1  int
+	I2  int
+	J1  int
+	J2  int
+}
+
+// SequenceMatcher compares sequence of strings. The basic
+// algorithm predates, and is a little fancier than, an algorithm
+// published in the late 1980's by Ratcliff and Obershelp under the
+// hyperbolic name "gestalt pattern matching".  The basic idea is to find
+// the longest contiguous matching subsequence that contains no "junk"
+// elements (R-O doesn't address junk).  The same idea is then applied
+// recursively to the pieces of the sequences to the left and to the right
+// of the matching subsequence.  This does not yield minimal edit
+// sequences, but does tend to yield matches that "look right" to people.
+//
+// SequenceMatcher tries to compute a "human-friendly diff" between two
+// sequences.  Unlike e.g. UNIX(tm) diff, the fundamental notion is the
+// longest *contiguous* & junk-free matching subsequence.  That's what
+// catches peoples' eyes.  The Windows(tm) windiff has another interesting
+// notion, pairing up elements that appear uniquely in each sequence.
+// That, and the method here, appear to yield more intuitive difference
+// reports than does diff.  This method appears to be the least vulnerable
+// to synching up on blocks of "junk lines", though (like blank lines in
+// ordinary text files, or maybe "<P>" lines in HTML files).  That may be
+// because this is the only method of the 3 that has a *concept* of
+// "junk" <wink>.
+//
+// Timing:  Basic R-O is cubic time worst case and quadratic time expected
+// case.  SequenceMatcher is quadratic time for the worst case and has
+// expected-case behavior dependent in a complicated way on how many
+// elements the sequences have in common; best case time is linear.
+type SequenceMatcher struct {
+	a              []string
+	b              []string
+	b2j            map[string][]int
+	IsJunk         func(string) bool
+	autoJunk       bool
+	bJunk          map[string]struct{}
+	matchingBlocks []Match
+	fullBCount     map[string]int
+	bPopular       map[string]struct{}
+	opCodes        []OpCode
+}
+
+// NewMatcher returns a new SequenceMatcher
+func NewMatcher(a, b []string) *SequenceMatcher {
+	m := SequenceMatcher{autoJunk: true}
+	m.SetSeqs(a, b)
+	return &m
+}
+
+// SetSeqs sets two sequences to be compared.
+func (m *SequenceMatcher) SetSeqs(a, b []string) {
+	m.SetSeq1(a)
+	m.SetSeq2(b)
+}
+
+// SetSeq1 sets the first sequence to be compared. The second sequence to be compared is
+// not changed.
+//
+// SequenceMatcher computes and caches detailed information about the second
+// sequence, so if you want to compare one sequence S against many sequences,
+// use .SetSeq2(s) once and call .SetSeq1(x) repeatedly for each of the other
+// sequences.
+//
+// See also SetSeqs() and SetSeq2().
+func (m *SequenceMatcher) SetSeq1(a []string) {
+	if &a == &m.a {
+		return
+	}
+	m.a = a
+	m.matchingBlocks = nil
+	m.opCodes = nil
+}
+
+// SetSeq2 sets the second sequence to be compared. The first sequence to be compared is
+// not changed.
+func (m *SequenceMatcher) SetSeq2(b []string) {
+	if &b == &m.b {
+		return
+	}
+	m.b = b
+	m.matchingBlocks = nil
+	m.opCodes = nil
+	m.fullBCount = nil
+	m.chainB()
+}
+
+func (m *SequenceMatcher) chainB() {
+	// Populate line -> index mapping
+	b2j := map[string][]int{}
+	for i, s := range m.b {
+		indices := b2j[s]
+		indices = append(indices, i)
+		b2j[s] = indices
+	}
+
+	// Purge junk elements
+	m.bJunk = map[string]struct{}{}
+	if m.IsJunk != nil {
+		junk := m.bJunk
+		for s := range b2j {
+			if m.IsJunk(s) {
+				junk[s] = struct{}{}
+			}
+		}
+		for s := range junk {
+			delete(b2j, s)
+		}
+	}
+
+	// Purge remaining popular elements
+	popular := map[string]struct{}{}
+	n := len(m.b)
+	if m.autoJunk && n >= 200 {
+		ntest := n/100 + 1
+		for s, indices := range b2j {
+			if len(indices) > ntest {
+				popular[s] = struct{}{}
+			}
+		}
+		for s := range popular {
+			delete(b2j, s)
+		}
+	}
+	m.bPopular = popular
+	m.b2j = b2j
+}
+
+func (m *SequenceMatcher) isBJunk(s string) bool {
+	_, ok := m.bJunk[s]
+	return ok
+}
+
+// Find longest matching block in a[alo:ahi] and b[blo:bhi].
+//
+// If IsJunk is not defined:
+//
+// Return (i,j,k) such that a[i:i+k] is equal to b[j:j+k], where
+//     alo <= i <= i+k <= ahi
+//     blo <= j <= j+k <= bhi
+// and for all (i',j',k') meeting those conditions,
+//     k >= k'
+//     i <= i'
+//     and if i == i', j <= j'
+//
+// In other words, of all maximal matching blocks, return one that
+// starts earliest in a, and of all those maximal matching blocks that
+// start earliest in a, return the one that starts earliest in b.
+//
+// If IsJunk is defined, first the longest matching block is
+// determined as above, but with the additional restriction that no
+// junk element appears in the block.  Then that block is extended as
+// far as possible by matching (only) junk elements on both sides.  So
+// the resulting block never matches on junk except as identical junk
+// happens to be adjacent to an "interesting" match.
+//
+// If no blocks match, return (alo, blo, 0).
+func (m *SequenceMatcher) findLongestMatch(alo, ahi, blo, bhi int) Match {
+	// CAUTION:  stripping common prefix or suffix would be incorrect.
+	// E.g.,
+	//    ab
+	//    acab
+	// Longest matching block is "ab", but if common prefix is
+	// stripped, it's "a" (tied with "b").  UNIX(tm) diff does so
+	// strip, so ends up claiming that ab is changed to acab by
+	// inserting "ca" in the middle.  That's minimal but unintuitive:
+	// "it's obvious" that someone inserted "ac" at the front.
+	// Windiff ends up at the same place as diff, but by pairing up
+	// the unique 'b's and then matching the first two 'a's.
+	besti, bestj, bestsize := alo, blo, 0
+
+	// find longest junk-free match
+	// during an iteration of the loop, j2len[j] = length of longest
+	// junk-free match ending with a[i-1] and b[j]
+	j2len := map[int]int{}
+	for i := alo; i != ahi; i++ {
+		// look at all instances of a[i] in b; note that because
+		// b2j has no junk keys, the loop is skipped if a[i] is junk
+		newj2len := map[int]int{}
+		for _, j := range m.b2j[m.a[i]] {
+			// a[i] matches b[j]
+			if j < blo {
+				continue
+			}
+			if j >= bhi {
+				break
+			}
+			k := j2len[j-1] + 1
+			newj2len[j] = k
+			if k > bestsize {
+				besti, bestj, bestsize = i-k+1, j-k+1, k
+			}
+		}
+		j2len = newj2len
+	}
+
+	// Extend the best by non-junk elements on each end.  In particular,
+	// "popular" non-junk elements aren't in b2j, which greatly speeds
+	// the inner loop above, but also means "the best" match so far
+	// doesn't contain any junk *or* popular non-junk elements.
+	for besti > alo && bestj > blo && !m.isBJunk(m.b[bestj-1]) &&
+		m.a[besti-1] == m.b[bestj-1] {
+		besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
+	}
+	for besti+bestsize < ahi && bestj+bestsize < bhi &&
+		!m.isBJunk(m.b[bestj+bestsize]) &&
+		m.a[besti+bestsize] == m.b[bestj+bestsize] {
+		bestsize += 1
+	}
+
+	// Now that we have a wholly interesting match (albeit possibly
+	// empty!), we may as well suck up the matching junk on each
+	// side of it too.  Can't think of a good reason not to, and it
+	// saves post-processing the (possibly considerable) expense of
+	// figuring out what to do with it.  In the case of an empty
+	// interesting match, this is clearly the right thing to do,
+	// because no other kind of match is possible in the regions.
+	for besti > alo && bestj > blo && m.isBJunk(m.b[bestj-1]) &&
+		m.a[besti-1] == m.b[bestj-1] {
+		besti, bestj, bestsize = besti-1, bestj-1, bestsize+1
+	}
+	for besti+bestsize < ahi && bestj+bestsize < bhi &&
+		m.isBJunk(m.b[bestj+bestsize]) &&
+		m.a[besti+bestsize] == m.b[bestj+bestsize] {
+		bestsize += 1
+	}
+
+	return Match{A: besti, B: bestj, Size: bestsize}
+}
+
+// GetMatchingBlocks returns a list of triples describing matching subsequences.
+//
+// Each triple is of the form (i, j, n), and means that
+// a[i:i+n] == b[j:j+n].  The triples are monotonically increasing in
+// i and in j. It's also guaranteed that if (i, j, n) and (i', j', n') are
+// adjacent triples in the list, and the second is not the last triple in the
+// list, then i+n != i' or j+n != j'. IOW, adjacent triples never describe
+// adjacent equal blocks.
+//
+// The last triple is a dummy, (len(a), len(b), 0), and is the only
+// triple with n==0.
+func (m *SequenceMatcher) GetMatchingBlocks() []Match {
+	if m.matchingBlocks != nil {
+		return m.matchingBlocks
+	}
+
+	var matchBlocks func(alo, ahi, blo, bhi int, matched []Match) []Match
+	matchBlocks = func(alo, ahi, blo, bhi int, matched []Match) []Match {
+		match := m.findLongestMatch(alo, ahi, blo, bhi)
+		i, j, k := match.A, match.B, match.Size
+		if match.Size > 0 {
+			if alo < i && blo < j {
+				matched = matchBlocks(alo, i, blo, j, matched)
+			}
+			matched = append(matched, match)
+			if i+k < ahi && j+k < bhi {
+				matched = matchBlocks(i+k, ahi, j+k, bhi, matched)
+			}
+		}
+		return matched
+	}
+	matched := matchBlocks(0, len(m.a), 0, len(m.b), nil)
+
+	// It's possible that we have adjacent equal blocks in the
+	// matching_blocks list now.
+	nonAdjacent := []Match{}
+	i1, j1, k1 := 0, 0, 0
+	for _, b := range matched {
+		// Is this block adjacent to i1, j1, k1?
+		i2, j2, k2 := b.A, b.B, b.Size
+		if i1+k1 == i2 && j1+k1 == j2 {
+			// Yes, so collapse them -- this just increases the length of
+			// the first block by the length of the second, and the first
+			// block so lengthened remains the block to compare against.
+			k1 += k2
+		} else {
+			// Not adjacent.  Remember the first block (k1==0 means it's
+			// the dummy we started with), and make the second block the
+			// new block to compare against.
+			if k1 > 0 {
+				nonAdjacent = append(nonAdjacent, Match{i1, j1, k1})
+			}
+			i1, j1, k1 = i2, j2, k2
+		}
+	}
+	if k1 > 0 {
+		nonAdjacent = append(nonAdjacent, Match{i1, j1, k1})
+	}
+
+	nonAdjacent = append(nonAdjacent, Match{len(m.a), len(m.b), 0})
+	m.matchingBlocks = nonAdjacent
+	return m.matchingBlocks
+}
+
+// GetOpCodes returns a list of 5-tuples describing how to turn a into b.
+//
+// Each tuple is of the form (tag, i1, i2, j1, j2).  The first tuple
+// has i1 == j1 == 0, and remaining tuples have i1 == the i2 from the
+// tuple preceding it, and likewise for j1 == the previous j2.
+//
+// The tags are characters, with these meanings:
+//
+// 'r' (replace):  a[i1:i2] should be replaced by b[j1:j2]
+//
+// 'd' (delete):   a[i1:i2] should be deleted, j1==j2 in this case.
+//
+// 'i' (insert):   b[j1:j2] should be inserted at a[i1:i1], i1==i2 in this case.
+//
+// 'e' (equal):    a[i1:i2] == b[j1:j2]
+func (m *SequenceMatcher) GetOpCodes() []OpCode {
+	if m.opCodes != nil {
+		return m.opCodes
+	}
+	i, j := 0, 0
+	matching := m.GetMatchingBlocks()
+	opCodes := make([]OpCode, 0, len(matching))
+	for _, m := range matching {
+		//  invariant:  we've pumped out correct diffs to change
+		//  a[:i] into b[:j], and the next matching block is
+		//  a[ai:ai+size] == b[bj:bj+size]. So we need to pump
+		//  out a diff to change a[i:ai] into b[j:bj], pump out
+		//  the matching block, and move (i,j) beyond the match
+		ai, bj, size := m.A, m.B, m.Size
+		tag := byte(0)
+		if i < ai && j < bj {
+			tag = 'r'
+		} else if i < ai {
+			tag = 'd'
+		} else if j < bj {
+			tag = 'i'
+		}
+		if tag > 0 {
+			opCodes = append(opCodes, OpCode{tag, i, ai, j, bj})
+		}
+		i, j = ai+size, bj+size
+		// the list of matching blocks is terminated by a
+		// sentinel with size 0
+		if size > 0 {
+			opCodes = append(opCodes, OpCode{'e', ai, i, bj, j})
+		}
+	}
+	m.opCodes = opCodes
+	return m.opCodes
+}
+
+// GetGroupedOpCodes isolates change clusters by eliminating ranges with no changes.
+//
+// Return a generator of groups with up to n lines of context.
+// Each group is in the same format as returned by GetOpCodes().
+func (m *SequenceMatcher) GetGroupedOpCodes(n int) [][]OpCode {
+	if n < 0 {
+		n = 3
+	}
+	codes := m.GetOpCodes()
+	if len(codes) == 0 {
+		codes = []OpCode{{'e', 0, 1, 0, 1}}
+	}
+	// Fixup leading and trailing groups if they show no changes.
+	if codes[0].Tag == 'e' {
+		c := codes[0]
+		i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2
+		codes[0] = OpCode{c.Tag, max(i1, i2-n), i2, max(j1, j2-n), j2}
+	}
+	if codes[len(codes)-1].Tag == 'e' {
+		c := codes[len(codes)-1]
+		i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2
+		codes[len(codes)-1] = OpCode{c.Tag, i1, min(i2, i1+n), j1, min(j2, j1+n)}
+	}
+	nn := n + n
+	groups := [][]OpCode{}
+	group := []OpCode{}
+	for _, c := range codes {
+		i1, i2, j1, j2 := c.I1, c.I2, c.J1, c.J2
+		// End the current group and start a new one whenever
+		// there is a large range with no changes.
+		if c.Tag == 'e' && i2-i1 > nn {
+			group = append(group, OpCode{c.Tag, i1, min(i2, i1+n),
+				j1, min(j2, j1+n)})
+			groups = append(groups, group)
+			group = []OpCode{}
+			i1, j1 = max(i1, i2-n), max(j1, j2-n)
+		}
+		group = append(group, OpCode{c.Tag, i1, i2, j1, j2})
+	}
+	if len(group) > 0 && !(len(group) == 1 && group[0].Tag == 'e') {
+		groups = append(groups, group)
+	}
+	return groups
+}
diff --git a/vendor/gotest.tools/internal/format/diff.go b/vendor/gotest.tools/internal/format/diff.go
new file mode 100644
index 0000000..c938c97
--- /dev/null
+++ b/vendor/gotest.tools/internal/format/diff.go
@@ -0,0 +1,161 @@
+package format
+
+import (
+	"bytes"
+	"fmt"
+	"strings"
+	"unicode"
+
+	"gotest.tools/internal/difflib"
+)
+
+const (
+	contextLines = 2
+)
+
+// DiffConfig for a unified diff
+type DiffConfig struct {
+	A    string
+	B    string
+	From string
+	To   string
+}
+
+// UnifiedDiff is a modified version of difflib.WriteUnifiedDiff with better
+// support for showing the whitespace differences.
+func UnifiedDiff(conf DiffConfig) string {
+	a := strings.SplitAfter(conf.A, "\n")
+	b := strings.SplitAfter(conf.B, "\n")
+	groups := difflib.NewMatcher(a, b).GetGroupedOpCodes(contextLines)
+	if len(groups) == 0 {
+		return ""
+	}
+
+	buf := new(bytes.Buffer)
+	writeFormat := func(format string, args ...interface{}) {
+		buf.WriteString(fmt.Sprintf(format, args...))
+	}
+	writeLine := func(prefix string, s string) {
+		buf.WriteString(prefix + s)
+	}
+	if hasWhitespaceDiffLines(groups, a, b) {
+		writeLine = visibleWhitespaceLine(writeLine)
+	}
+	formatHeader(writeFormat, conf)
+	for _, group := range groups {
+		formatRangeLine(writeFormat, group)
+		for _, opCode := range group {
+			in, out := a[opCode.I1:opCode.I2], b[opCode.J1:opCode.J2]
+			switch opCode.Tag {
+			case 'e':
+				formatLines(writeLine, " ", in)
+			case 'r':
+				formatLines(writeLine, "-", in)
+				formatLines(writeLine, "+", out)
+			case 'd':
+				formatLines(writeLine, "-", in)
+			case 'i':
+				formatLines(writeLine, "+", out)
+			}
+		}
+	}
+	return buf.String()
+}
+
+// hasWhitespaceDiffLines returns true if any diff groups is only different
+// because of whitespace characters.
+func hasWhitespaceDiffLines(groups [][]difflib.OpCode, a, b []string) bool {
+	for _, group := range groups {
+		in, out := new(bytes.Buffer), new(bytes.Buffer)
+		for _, opCode := range group {
+			if opCode.Tag == 'e' {
+				continue
+			}
+			for _, line := range a[opCode.I1:opCode.I2] {
+				in.WriteString(line)
+			}
+			for _, line := range b[opCode.J1:opCode.J2] {
+				out.WriteString(line)
+			}
+		}
+		if removeWhitespace(in.String()) == removeWhitespace(out.String()) {
+			return true
+		}
+	}
+	return false
+}
+
+func removeWhitespace(s string) string {
+	var result []rune
+	for _, r := range s {
+		if !unicode.IsSpace(r) {
+			result = append(result, r)
+		}
+	}
+	return string(result)
+}
+
+func visibleWhitespaceLine(ws func(string, string)) func(string, string) {
+	mapToVisibleSpace := func(r rune) rune {
+		switch r {
+		case '\n':
+		case ' ':
+			return '·'
+		case '\t':
+			return '▷'
+		case '\v':
+			return '▽'
+		case '\r':
+			return '↵'
+		case '\f':
+			return '↓'
+		default:
+			if unicode.IsSpace(r) {
+				return '�'
+			}
+		}
+		return r
+	}
+	return func(prefix, s string) {
+		ws(prefix, strings.Map(mapToVisibleSpace, s))
+	}
+}
+
+func formatHeader(wf func(string, ...interface{}), conf DiffConfig) {
+	if conf.From != "" || conf.To != "" {
+		wf("--- %s\n", conf.From)
+		wf("+++ %s\n", conf.To)
+	}
+}
+
+func formatRangeLine(wf func(string, ...interface{}), group []difflib.OpCode) {
+	first, last := group[0], group[len(group)-1]
+	range1 := formatRangeUnified(first.I1, last.I2)
+	range2 := formatRangeUnified(first.J1, last.J2)
+	wf("@@ -%s +%s @@\n", range1, range2)
+}
+
+// Convert range to the "ed" format
+func formatRangeUnified(start, stop int) string {
+	// Per the diff spec at http://www.unix.org/single_unix_specification/
+	beginning := start + 1 // lines start numbering with one
+	length := stop - start
+	if length == 1 {
+		return fmt.Sprintf("%d", beginning)
+	}
+	if length == 0 {
+		beginning-- // empty ranges begin at line just before the range
+	}
+	return fmt.Sprintf("%d,%d", beginning, length)
+}
+
+func formatLines(writeLine func(string, string), prefix string, lines []string) {
+	for _, line := range lines {
+		writeLine(prefix, line)
+	}
+	// Add a newline if the last line is missing one so that the diff displays
+	// properly.
+	if !strings.HasSuffix(lines[len(lines)-1], "\n") {
+		writeLine("", "\n")
+	}
+}
diff --git a/vendor/gotest.tools/internal/format/format.go b/vendor/gotest.tools/internal/format/format.go
new file mode 100644
index 0000000..8f6494f
--- /dev/null
+++ b/vendor/gotest.tools/internal/format/format.go
@@ -0,0 +1,27 @@
+package format // import "gotest.tools/internal/format"
+
+import "fmt"
+
+// Message accepts a msgAndArgs varargs and formats it using fmt.Sprintf
+func Message(msgAndArgs ...interface{}) string {
+	switch len(msgAndArgs) {
+	case 0:
+		return ""
+	case 1:
+		return fmt.Sprintf("%v", msgAndArgs[0])
+	default:
+		return fmt.Sprintf(msgAndArgs[0].(string), msgAndArgs[1:]...)
+	}
+}
+
+// WithCustomMessage accepts one or two messages and formats them appropriately
+func WithCustomMessage(source string, msgAndArgs ...interface{}) string {
+	custom := Message(msgAndArgs...)
+	switch {
+	case custom == "":
+		return source
+	case source == "":
+		return custom
+	}
+	return fmt.Sprintf("%s: %s", source, custom)
+}
diff --git a/vendor/gotest.tools/internal/source/defers.go b/vendor/gotest.tools/internal/source/defers.go
new file mode 100644
index 0000000..66cfafb
--- /dev/null
+++ b/vendor/gotest.tools/internal/source/defers.go
@@ -0,0 +1,53 @@
+package source
+
+import (
+	"go/ast"
+	"go/token"
+
+	"github.com/pkg/errors"
+)
+
+func scanToDeferLine(fileset *token.FileSet, node ast.Node, lineNum int) ast.Node {
+	var matchedNode ast.Node
+	ast.Inspect(node, func(node ast.Node) bool {
+		switch {
+		case node == nil || matchedNode != nil:
+			return false
+		case fileset.Position(node.End()).Line == lineNum:
+			if funcLit, ok := node.(*ast.FuncLit); ok {
+				matchedNode = funcLit
+				return false
+			}
+		}
+		return true
+	})
+	debug("defer line node: %s", debugFormatNode{matchedNode})
+	return matchedNode
+}
+
+func guessDefer(node ast.Node) (ast.Node, error) {
+	defers := collectDefers(node)
+	switch len(defers) {
+	case 0:
+		return nil, errors.New("failed to expression in defer")
+	case 1:
+		return defers[0].Call, nil
+	default:
+		return nil, errors.Errorf(
+			"ambiguous call expression: multiple (%d) defers in call block",
+			len(defers))
+	}
+}
+
+func collectDefers(node ast.Node) []*ast.DeferStmt {
+	var defers []*ast.DeferStmt
+	ast.Inspect(node, func(node ast.Node) bool {
+		if d, ok := node.(*ast.DeferStmt); ok {
+			defers = append(defers, d)
+			debug("defer: %s", debugFormatNode{d})
+			return false
+		}
+		return true
+	})
+	return defers
+}
diff --git a/vendor/gotest.tools/internal/source/source.go b/vendor/gotest.tools/internal/source/source.go
new file mode 100644
index 0000000..8a5d0e8
--- /dev/null
+++ b/vendor/gotest.tools/internal/source/source.go
@@ -0,0 +1,166 @@
+package source // import "gotest.tools/internal/source"
+
+import (
+	"bytes"
+	"fmt"
+	"go/ast"
+	"go/format"
+	"go/parser"
+	"go/token"
+	"os"
+	"runtime"
+	"strconv"
+	"strings"
+
+	"github.com/pkg/errors"
+)
+
+const baseStackIndex = 1
+
+// FormattedCallExprArg returns the argument from an ast.CallExpr at the
+// index in the call stack. The argument is formatted using FormatNode.
+func FormattedCallExprArg(stackIndex int, argPos int) (string, error) {
+	args, err := CallExprArgs(stackIndex + 1)
+	if err != nil {
+		return "", err
+	}
+	if argPos >= len(args) {
+		return "", errors.New("failed to find expression")
+	}
+	return FormatNode(args[argPos])
+}
+
+// CallExprArgs returns the ast.Expr slice for the args of an ast.CallExpr at
+// the index in the call stack.
+func CallExprArgs(stackIndex int) ([]ast.Expr, error) {
+	_, filename, lineNum, ok := runtime.Caller(baseStackIndex + stackIndex)
+	if !ok {
+		return nil, errors.New("failed to get call stack")
+	}
+	debug("call stack position: %s:%d", filename, lineNum)
+
+	node, err := getNodeAtLine(filename, lineNum)
+	if err != nil {
+		return nil, err
+	}
+	debug("found node: %s", debugFormatNode{node})
+
+	return getCallExprArgs(node)
+}
+
+func getNodeAtLine(filename string, lineNum int) (ast.Node, error) {
+	fileset := token.NewFileSet()
+	astFile, err := parser.ParseFile(fileset, filename, nil, parser.AllErrors)
+	if err != nil {
+		return nil, errors.Wrapf(err, "failed to parse source file: %s", filename)
+	}
+
+	if node := scanToLine(fileset, astFile, lineNum); node != nil {
+		return node, nil
+	}
+	if node := scanToDeferLine(fileset, astFile, lineNum); node != nil {
+		node, err := guessDefer(node)
+		if err != nil || node != nil {
+			return node, err
+		}
+	}
+	return nil, errors.Errorf(
+		"failed to find an expression on line %d in %s", lineNum, filename)
+}
+
+func scanToLine(fileset *token.FileSet, node ast.Node, lineNum int) ast.Node {
+	var matchedNode ast.Node
+	ast.Inspect(node, func(node ast.Node) bool {
+		switch {
+		case node == nil || matchedNode != nil:
+			return false
+		case nodePosition(fileset, node).Line == lineNum:
+			matchedNode = node
+			return false
+		}
+		return true
+	})
+	return matchedNode
+}
+
+// In golang 1.9 the line number changed from being the line where the statement
+// ended to the line where the statement began.
+func nodePosition(fileset *token.FileSet, node ast.Node) token.Position {
+	if goVersionBefore19 {
+		return fileset.Position(node.End())
+	}
+	return fileset.Position(node.Pos())
+}
+
+var goVersionBefore19 = func() bool {
+	version := runtime.Version()
+	// not a release version
+	if !strings.HasPrefix(version, "go") {
+		return false
+	}
+	version = strings.TrimPrefix(version, "go")
+	parts := strings.Split(version, ".")
+	if len(parts) < 2 {
+		return false
+	}
+	minor, err := strconv.ParseInt(parts[1], 10, 32)
+	return err == nil && parts[0] == "1" && minor < 9
+}()
+
+func getCallExprArgs(node ast.Node) ([]ast.Expr, error) {
+	visitor := &callExprVisitor{}
+	ast.Walk(visitor, node)
+	if visitor.expr == nil {
+		return nil, errors.New("failed to find call expression")
+	}
+	debug("callExpr: %s", debugFormatNode{visitor.expr})
+	return visitor.expr.Args, nil
+}
+
+type callExprVisitor struct {
+	expr *ast.CallExpr
+}
+
+func (v *callExprVisitor) Visit(node ast.Node) ast.Visitor {
+	if v.expr != nil || node == nil {
+		return nil
+	}
+	debug("visit: %s", debugFormatNode{node})
+
+	switch typed := node.(type) {
+	case *ast.CallExpr:
+		v.expr = typed
+		return nil
+	case *ast.DeferStmt:
+		ast.Walk(v, typed.Call.Fun)
+		return nil
+	}
+	return v
+}
+
+// FormatNode using go/format.Node and return the result as a string
+func FormatNode(node ast.Node) (string, error) {
+	buf := new(bytes.Buffer)
+	err := format.Node(buf, token.NewFileSet(), node)
+	return buf.String(), err
+}
+
+var debugEnabled = os.Getenv("GOTESTTOOLS_DEBUG") != ""
+
+func debug(format string, args ...interface{}) {
+	if debugEnabled {
+		fmt.Fprintf(os.Stderr, "DEBUG: "+format+"\n", args...)
+	}
+}
+
+type debugFormatNode struct {
+	ast.Node
+}
+
+func (n debugFormatNode) String() string {
+	out, err := FormatNode(n.Node)
+	if err != nil {
+		return fmt.Sprintf("failed to format %s: %s", n.Node, err)
+	}
+	return fmt.Sprintf("(%T) %s", n.Node, out)
+}
