Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,17 @@ func CallerFrame() runtime.Frame {

// FileWithLineNum return the file name and line number of the current file
func FileWithLineNum() string {
frame := CallerFrame()
if frame.PC != 0 {
return string(strconv.AppendInt(append([]byte(frame.File), ':'), int64(frame.Line), 10))
pcs := [13]uintptr{}
// the third caller usually from gorm internal
len := runtime.Callers(3, pcs[:])
frames := runtime.CallersFrames(pcs[:len])
for i := 0; i < len; i++ {
// second return value is "more", not "ok"
frame, _ := frames.Next()
if (!strings.HasPrefix(frame.File, gormSourceDir) ||
strings.HasSuffix(frame.File, "_test.go")) && !strings.HasSuffix(frame.File, ".gen.go") {
return string(strconv.AppendInt(append([]byte(frame.File), ':'), int64(frame.Line), 10))
}
Comment on lines +57 to +67
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Recommended

[Maintainability] [CodeDuplication] The FileWithLineNum() function now duplicates the exact logic from CallerFrame(). Both functions contain identical stack traversal code:

  • Both call runtime.Callers(3, pcs[:])
  • Both iterate through frames with the same filtering logic
  • Both check for gormSourceDir, _test.go, and .gen.go files

Consider refactoring to eliminate this duplication:

func FileWithLineNum() string {
	frame := CallerFrame()
	if frame.PC != 0 {
		return string(strconv.AppendInt(append([]byte(frame.File), ':'), int64(frame.Line), 10))
	}
	return ""
}

This was the original implementation before this PR, which properly reused CallerFrame(). The duplication increases maintenance burden - any future changes to the filtering logic would need to be made in two places.

Context for Agents
[CodeDuplication] The `FileWithLineNum()` function now duplicates the exact logic from `CallerFrame()`. Both functions contain identical stack traversal code:

- Both call `runtime.Callers(3, pcs[:])`
- Both iterate through frames with the same filtering logic
- Both check for `gormSourceDir`, `_test.go`, and `.gen.go` files

Consider refactoring to eliminate this duplication:

```go
func FileWithLineNum() string {
	frame := CallerFrame()
	if frame.PC != 0 {
		return string(strconv.AppendInt(append([]byte(frame.File), ':'), int64(frame.Line), 10))
	}
	return ""
}
```

This was the original implementation before this PR, which properly reused `CallerFrame()`. The duplication increases maintenance burden - any future changes to the filtering logic would need to be made in two places.

File: utils/utils.go
Line: 67

}

return ""
Expand Down
19 changes: 19 additions & 0 deletions utils/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import (
"database/sql"
"database/sql/driver"
"errors"
"fmt"
"math"
"runtime"
"strings"
"testing"
"time"
Expand Down Expand Up @@ -199,3 +201,20 @@ func TestRTrimSlice(t *testing.T) {
})
}
}

// Define the where function for testing
func where() string {
return FileWithLineNum()
}

func TestFileWithLineNum(t *testing.T) {
_, _, expectedLine, _ := runtime.Caller(0)
actual := where() // Called from next line
expectedLine++ // where() is called one line after Caller(0)

expectedFile := "utils_test.go"
expectedStr := fmt.Sprintf("%s:%d", expectedFile, expectedLine)
if !strings.Contains(actual, expectedStr) {
t.Errorf("Expected %s, but got %s", expectedStr, actual)
}
}
Loading