diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..77b7be5 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,10 @@ +version: 2 +updates: +- package-ecosystem: gomod + directory: / + schedule: + interval: weekly +- package-ecosystem: github-actions + directory: / + schedule: + interval: weekly diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index db23318..eb21888 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -7,10 +7,10 @@ jobs: test: runs-on: ubuntu-latest steps: - - uses: actions/setup-go@v1 + - uses: actions/setup-go@v2 with: - go-version: 1.13.x - - uses: actions/checkout@v2 + go-version: 1.18.x + - uses: actions/checkout@v3 - name: Build run: go build . - name: Test diff --git a/.gitignore b/.gitignore index 1f0a99f..b2d4781 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ _go* _test* _obj +/.idea diff --git a/formatter.go b/formatter.go index 5bf7e15..1d2eb7a 100644 --- a/formatter.go +++ b/formatter.go @@ -93,6 +93,24 @@ type visit struct { typ reflect.Type } +func (p *printer) catchPanic(v reflect.Value, method string) { + if r := recover(); r != nil { + if v.Kind() == reflect.Ptr && v.IsNil() { + writeByte(p, '(') + io.WriteString(p, v.Type().String()) + io.WriteString(p, ")(nil)") + return + } + writeByte(p, '(') + io.WriteString(p, v.Type().String()) + io.WriteString(p, ")(PANIC=calling method ") + io.WriteString(p, strconv.Quote(method)) + io.WriteString(p, ": ") + fmt.Fprint(p, r) + writeByte(p, ')') + } +} + func (p *printer) printValue(v reflect.Value, showType, quote bool) { if p.depth > 10 { io.WriteString(p, "!%v(DEPTH EXCEEDED)") @@ -102,6 +120,7 @@ func (p *printer) printValue(v reflect.Value, showType, quote bool) { if v.IsValid() && v.CanInterface() { i := v.Interface() if goStringer, ok := i.(fmt.GoStringer); ok { + defer p.catchPanic(v, "GoString") io.WriteString(p, goStringer.GoString()) return } diff --git a/formatter_test.go b/formatter_test.go index df40e4c..b8c2f58 100644 --- a/formatter_test.go +++ b/formatter_test.go @@ -98,7 +98,7 @@ var gosyntax = []test{ `[]string{"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"}`, }, {F(5), "pretty.F(5)"}, - { NewStructWithPrivateFields("foo"), `NewStructWithPrivateFields("foo")`}, + {NewStructWithPrivateFields("foo"), `NewStructWithPrivateFields("foo")`}, { SA{&T{1, 2}, T{3, 4}}, `pretty.SA{ @@ -181,6 +181,41 @@ var gosyntax = []test{ time.Date(2009, 11, 17, 20, 34, 58, 651387237, time.UTC), "time.Date(2009, time.November, 17, 20, 34, 58, 651387237, time.UTC)", }, + {(*time.Time)(nil), "(*time.Time)(nil)"}, + {&ValueGoString{"vgs"}, `VGS vgs`}, + {(*ValueGoString)(nil), `(*pretty.ValueGoString)(nil)`}, + {(*VGSWrapper)(nil), `(*pretty.VGSWrapper)(nil)`}, + {&PointerGoString{"pgs"}, `PGS pgs`}, + {(*PointerGoString)(nil), "(*pretty.PointerGoString)(nil)"}, + {&PanicGoString{"oops!"}, `(*pretty.PanicGoString)(PANIC=calling method "GoString": oops!)`}, +} + +type ValueGoString struct { + s string +} + +func (g ValueGoString) GoString() string { + return "VGS " + g.s +} + +type VGSWrapper struct { + ValueGoString +} + +type PointerGoString struct { + s string +} + +func (g *PointerGoString) GoString() string { + return "PGS " + g.s +} + +type PanicGoString struct { + s string +} + +func (g *PanicGoString) GoString() string { + panic(g.s) } func TestGoSyntax(t *testing.T) { diff --git a/go.mod b/go.mod index 94ffbe2..31042e3 100644 --- a/go.mod +++ b/go.mod @@ -1,8 +1,8 @@ module github.com/zk-org/pretty -go 1.12 +go 1.18 require ( github.com/kr/text v0.2.0 - github.com/rogpeppe/go-internal v1.6.1 + github.com/rogpeppe/go-internal v1.9.0 ) diff --git a/go.sum b/go.sum index 0d561de..4a97a0e 100644 --- a/go.sum +++ b/go.sum @@ -1,11 +1,5 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k= -github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=