...
1
16
17 package naming
18
19 import (
20 "fmt"
21 "regexp"
22 goruntime "runtime"
23 "runtime/debug"
24 "strconv"
25 "strings"
26 )
27
28
29
30 func GetNameFromCallsite(ignoredPackages ...string) string {
31 name := "????"
32 const maxStack = 10
33 for i := 1; i < maxStack; i++ {
34 _, file, line, ok := goruntime.Caller(i)
35 if !ok {
36 file, line, ok = extractStackCreator()
37 if !ok {
38 break
39 }
40 i += maxStack
41 }
42 if hasPackage(file, append(ignoredPackages, "/runtime/asm_")) {
43 continue
44 }
45
46 file = trimPackagePrefix(file)
47 name = fmt.Sprintf("%s:%d", file, line)
48 break
49 }
50 return name
51 }
52
53
54 func hasPackage(file string, ignoredPackages []string) bool {
55 for _, ignoredPackage := range ignoredPackages {
56 if strings.Contains(file, ignoredPackage) {
57 return true
58 }
59 }
60 return false
61 }
62
63
64 func trimPackagePrefix(file string) string {
65 if l := strings.LastIndex(file, "/vendor/"); l >= 0 {
66 return file[l+len("/vendor/"):]
67 }
68 if l := strings.LastIndex(file, "/src/"); l >= 0 {
69 return file[l+5:]
70 }
71 if l := strings.LastIndex(file, "/pkg/"); l >= 0 {
72 return file[l+1:]
73 }
74 return file
75 }
76
77 var stackCreator = regexp.MustCompile(`(?m)^created by (.*)\n\s+(.*):(\d+) \+0x[[:xdigit:]]+$`)
78
79
80
81
82 func extractStackCreator() (string, int, bool) {
83 stack := debug.Stack()
84 matches := stackCreator.FindStringSubmatch(string(stack))
85 if len(matches) != 4 {
86 return "", 0, false
87 }
88 line, err := strconv.Atoi(matches[3])
89 if err != nil {
90 return "", 0, false
91 }
92 return matches[2], line, true
93 }
94
View as plain text