arnaucube
arnaucube/mirror-to-giteaPublic Self-hosted repository
mirror-to-gitea/vendor/github.com/onsi/ginkgo/internal/codelocation/code_location.go
vendor/github.com/onsi/ginkgo/internal/codelocation/code_location.goRaw
 1package codelocation
 2
 3import (
 4	"regexp"
 5	"runtime"
 6	"runtime/debug"
 7	"strings"
 8
 9	"github.com/onsi/ginkgo/types"
10)
11
12func New(skip int) types.CodeLocation {
13	_, file, line, _ := runtime.Caller(skip + 1)
14	stackTrace := PruneStack(string(debug.Stack()), skip+1)
15	return types.CodeLocation{FileName: file, LineNumber: line, FullStackTrace: stackTrace}
16}
17
18// PruneStack removes references to functions that are internal to Ginkgo
19// and the Go runtime from a stack string and a certain number of stack entries
20// at the beginning of the stack. The stack string has the format
21// as returned by runtime/debug.Stack. The leading goroutine information is
22// optional and always removed if present. Beware that runtime/debug.Stack
23// adds itself as first entry, so typically skip must be >= 1 to remove that
24// entry.
25func PruneStack(fullStackTrace string, skip int) string {
26	stack := strings.Split(fullStackTrace, "\n")
27	// Ensure that the even entries are the method names and the
28	// the odd entries the source code information.
29	if len(stack) > 0 && strings.HasPrefix(stack[0], "goroutine ") {
30		// Ignore "goroutine 29 [running]:" line.
31		stack = stack[1:]
32	}
33	// The "+1" is for skipping over the initial entry, which is
34	// runtime/debug.Stack() itself.
35	if len(stack) > 2*(skip+1) {
36		stack = stack[2*(skip+1):]
37	}
38	prunedStack := []string{}
39	re := regexp.MustCompile(`\/ginkgo\/|\/pkg\/testing\/|\/pkg\/runtime\/`)
40	for i := 0; i < len(stack)/2; i++ {
41		// We filter out based on the source code file name.
42		if !re.Match([]byte(stack[i*2+1])) {
43			prunedStack = append(prunedStack, stack[i*2])
44			prunedStack = append(prunedStack, stack[i*2+1])
45		}
46	}
47	return strings.Join(prunedStack, "\n")
48}