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}