vektra / mockery

A mock code autogenerator for Go
https://vektra.github.io/mockery/
BSD 3-Clause "New" or "Revised" License
6.09k stars 409 forks source link

Go 1.23: Mock generation fails with alias types #803

Closed spencercornish-wk closed 1 month ago

spencercornish-wk commented 2 months ago

Description

In the latest version of go, a change was made to the generation of Alias types. From the release notes:

By default, go/types now produces Alias type nodes for type aliases. This behavior can be controlled by the GODEBUG gotypesalias flag. Its default has changed from 0 in Go 1.22 to 1 in Go 1.23.

This means that the latest version of Mockery fails to generate mocks which include alias types in the interface.

Mockery Version

Latest at time of writing (v2.44.1)

Go Version

Latest at time of writing (v1.23.0)

Installation Method

Steps to Reproduce

  1. Write an interface that contains an alias type in a function signature
  2. Try to generate mocks on it
  3. See panic

Minimum-reproducible code:

package mypackage

import (
    "os"
)

// Where os.DirEntry is an alias for the fs.DirEntry type
type MyInterface interface {
    GetFiles() []os.DirEntry
}

.mockery/yml:

  [...]/mypackage:
    config:
      inpackage: true
      dir: "{{.InterfaceDir}}"
    interfaces:
      MyInterface:

Expected Behavior

Mocks to generate

Actual Behavior

This panic + stacktrace:

13 Aug 24 14:53 MDT INF generating mocks for interface dry-run=false interface=MyInterface qualified-name=github.com/[...]/mypackage version=v2.44.1
panic: un-namable type: &types.Alias{obj:(*types.TypeName)(0x14001677400), orig:(*types.Alias)(0x14001747400), tparams:(*types.TypeParamList)(nil), targs:(*types.TypeList)(nil), fromRHS:(*types.Named)(0x14001678070), actual:(*types.Named)(0x14001678070)} (*types.Alias)

goroutine 1 [running]:
github.com/vektra/mockery/v2/pkg.(*Generator).renderType(0x14000c46100?, {0x100fdf888?, 0x140035887e0?}, {0x100fddb40?, 0x14001747400?})
    [$GOPATH]/go/pkg/mod/github.com/vektra/mockery/v2@v2.44.1/pkg/generator.go:627 +0x890
github.com/vektra/mockery/v2/pkg.(*Generator).renderType(0x14000c46100, {0x100fdf888, 0x140035887e0}, {0x100fdca38?, 0x14001760b00})
    [$GOPATH]/go/pkg/mod/github.com/vektra/mockery/v2@v2.44.1/pkg/generator.go:542 +0x64c
github.com/vektra/mockery/v2/pkg.(*Generator).addImportsFromTuple(0x14000c46100, {0x100fdf888, 0x140035887e0}, 0x1400176acf0)
    [$GOPATH]/go/pkg/mod/github.com/vektra/mockery/v2@v2.44.1/pkg/generator.go:152 +0x54
github.com/vektra/mockery/v2/pkg.(*Generator).populateImports(0x14000c46100, {0x100fdf888, 0x140035887e0})
    [$GOPATH]/go/pkg/mod/github.com/vektra/mockery/v2@v2.44.1/pkg/generator.go:142 +0x134
github.com/vektra/mockery/v2/pkg.(*Generator).GeneratePrologue(0x14000c46100, {0x100fdf888, 0x140035887e0}, {0x14000800fc0, 0x57})
    [$GOPATH]/go/pkg/mod/github.com/vektra/mockery/v2@v2.44.1/pkg/generator.go:420 +0x30
github.com/vektra/mockery/v2/pkg.(*Generator).GenerateAll(0x14000c46100, {0x100fdf888, 0x140035887e0})
    [$GOPATH]/go/pkg/mod/github.com/vektra/mockery/v2@v2.44.1/pkg/generator.go:116 +0xfc
github.com/vektra/mockery/v2/pkg.(*Outputter).Generate(0x140138d1c08, {0x100fdf888, 0x140035887b0}, 0x1400aec3650)
    [$GOPATH]/go/pkg/mod/github.com/vektra/mockery/v2@v2.44.1/pkg/outputter.go:352 +0x554
github.com/vektra/mockery/v2/cmd.(*RootApp).Run(0x140000f12c0)
    [$GOPATH]/go/pkg/mod/github.com/vektra/mockery/v2@v2.44.1/cmd/mockery.go:268 +0x1728
github.com/vektra/mockery/v2/cmd.NewRootCmd.func1(0x140001b6a00?, {0x100ddd23a?, 0x4?, 0x100ddd23e?})
    [$GOPATH]/go/pkg/mod/github.com/vektra/mockery/v2@v2.44.1/cmd/mockery.go:46 +0x48
github.com/spf13/cobra.(*Command).execute(0x140000fe608, {0x140000a8010, 0x0, 0x0})
    [$GOPATH]/go/pkg/mod/github.com/spf13/cobra@v1.8.0/command.go:987 +0x81c
github.com/spf13/cobra.(*Command).ExecuteC(0x140000fe608)
    [$GOPATH]/go/pkg/mod/github.com/spf13/cobra@v1.8.0/command.go:1115 +0x344
github.com/spf13/cobra.(*Command).Execute(...)
    [$GOPATH]/go/pkg/mod/github.com/spf13/cobra@v1.8.0/command.go:1039
github.com/vektra/mockery/v2/cmd.Execute()
    [$GOPATH]/go/pkg/mod/github.com/vektra/mockery/v2@v2.44.1/cmd/mockery.go:105 +0x20
main.main()
    [$GOPATH]/go/pkg/mod/github.com/vektra/mockery/v2@v2.44.1/main.go:8 +0x1c

Temporary Workarounds

Clarification for workaround (2) above:

generate the mockery binary as usual but run it with GODEBUG=gotypesalias=0 $(MOCKERY)

yurishkuro commented 2 months ago

Clarification for workaround (2) above:

LandonTClipp commented 2 months ago

I believe gotypealias being enabled would help solve some outstanding problems, like with mockery incorrectly following a type alias back to its underlying type (which is the reason replace-types exists).

I would be of the opinion that we just fix mockery to support this and check to see how it behaves now with aliases, particularly in the test cases that exercise replace-types. Like, can we just completely disregard replace-types now? That would be cool.

This is a high priority bug to fix. I'll solicit takers for this one. If not, maybe I can get to it in a few weeks.

RangelReale commented 2 months ago

I believe gotypealias being enabled would help solve some outstanding problems, like with mockery incorrectly following a type alias back to its underlying type (which is the reason replace-types exists).

I think this was made exactly to fix the replace-types problem, with this, it would be possible to remove replace-types (once Go 1.23 is the last supported version.

I'll see if I can find some time to look at it this week.

RangelReale commented 2 months ago

Another quick temporary fix is adding this to a Go 1.23 go.mod file:

godebug (
    gotypesalias=0
)
RangelReale commented 2 months ago

Created fix PR.

yurishkuro commented 1 month ago

Thanks for the fix! Confirmed it's working https://github.com/jaegertracing/jaeger/pull/6025 without gotypesalias=0