@@ -10,6 +10,7 @@ import (
1010 "runtime/debug"
1111 "strconv"
1212 "strings"
13+ "sync"
1314)
1415
1516// RunOptions specifies options for running a command.
@@ -94,22 +95,22 @@ func checkAndSetRunOptions(opt *RunOptions) *RunOptions {
9495}
9596
9697var (
98+ once sync.Once
9799 goModuleName string
98100)
99101
100- // GoModuleName returns the Go module name of the current application.
101- func GoModuleName () string {
102- if goModuleName == "" {
102+ func getGoModuleName () string {
103+ once .Do (func () {
103104 if info , ok := debug .ReadBuildInfo (); ok && info .Main .Path != "" {
104105 goModuleName = info .Main .Path
105106 }
106- }
107+ })
107108 return goModuleName
108109}
109110
110111func location (skip int ) string {
111112 var pcs [1 ]uintptr
112- // Need to add 2 to skip to account for this function and runtime.Callers.
113+ // Need to add 2 to skip to account for this function and runtime.Callers
113114 n := runtime .Callers (skip + 2 , pcs [:])
114115 if n == 0 {
115116 return "unknown:0"
@@ -118,8 +119,8 @@ func location(skip int) string {
118119 frame , _ := runtime .CallersFrames (pcs [:n ]).Next ()
119120
120121 // Trim the module name from both function and file paths for cleaner output
121- fn := strings .TrimPrefix (frame .Function , GoModuleName ()+ "/" )
122- file := strings .TrimPrefix (frame .File , GoModuleName ()+ "/" )
122+ fn := strings .TrimPrefix (frame .Function , getGoModuleName ()+ "/" )
123+ file := strings .TrimPrefix (frame .File , getGoModuleName ()+ "/" )
123124
124125 return fn + " " + file + ":" + strconv .Itoa (frame .Line )
125126}
0 commit comments