Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Go 1.23 types.Alias handling #808

Merged
merged 8 commits into from
Sep 28, 2024
Merged
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
2 changes: 1 addition & 1 deletion .github/workflows/testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
strategy:
matrix:
os: [ macos-latest, ubuntu-latest]
go_vers: ['1.21', '1.22']
go_vers: ['1.22', '1.23']
steps:
- uses: actions/checkout@v2
with:
Expand Down
2 changes: 1 addition & 1 deletion .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ linters:
- typecheck
- contextcheck
- durationcheck
- exportloopref
- copyloopvar
- gocheckcompilerdirectives
- gosec
- loggercheck
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
module github.com/vektra/mockery/v2

go 1.22
go 1.23

toolchain go1.22.0
toolchain go1.23.1

require (
github.com/chigopher/pathlib v0.19.1
Expand Down
4 changes: 2 additions & 2 deletions go.work
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
go 1.22
go 1.23.1

toolchain go1.22.0
toolchain go1.23.1

use (
.
Expand Down
780 changes: 780 additions & 0 deletions go.work.sum

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ func (c *Config) GetPackages(ctx context.Context) ([]string, error) {
if !ok {
msg := "packages section is of the wrong type"
log.Error().Msg(msg)
return []string{}, fmt.Errorf(msg)
return []string{}, errors.New(msg)
}
packageList := []string{}
for key := range packageSection {
Expand Down Expand Up @@ -395,7 +395,7 @@ func (c *Config) GetInterfaceConfig(ctx context.Context, packageName string, int
return []*Config{pkgConfigCopy}, nil
}
msgString := "bad type provided for interface config"
log.Error().Msgf(msgString)
log.Error().Msg(msgString)
return nil, stackerr.NewStackErr(errors.New(msgString))
}

Expand Down Expand Up @@ -795,7 +795,7 @@ func (c *Config) mergeInConfig(ctx context.Context) error {
// wasn't defined in the yaml.
msg := "config section does not exist for package, this should never happen"
pkgLog.Error().Msg(msg)
return fmt.Errorf(msg)
return errors.New(msg)
}

pkgLog.Trace().Msg("got config section for package")
Expand Down
35 changes: 24 additions & 11 deletions pkg/generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,7 @@ func (g *Generator) GeneratePrologueNote(note string) {
}
prologue += ". DO NOT EDIT.\n"

g.printf(prologue)
g.print(prologue)
if note != "" {
g.printf("\n")
for _, n := range strings.Split(note, "\\n") {
Expand Down Expand Up @@ -465,6 +465,10 @@ func (g *Generator) GenerateBuildTags(buildTags string) {
// type.
var ErrNotInterface = errors.New("expression not an interface")

func (g *Generator) print(s string) {
fmt.Fprint(&g.buf, s)
}

func (g *Generator) printf(s string, vals ...interface{}) {
fmt.Fprintf(&g.buf, s, vals...)
}
Expand Down Expand Up @@ -495,19 +499,28 @@ type namer interface {
Name() string
}

func (g *Generator) renderNamedType(ctx context.Context, t interface {
Obj() *types.TypeName
TypeArgs() *types.TypeList
}) string {
name := g.getPackageScopedType(ctx, t.Obj())
if t.TypeArgs() == nil || t.TypeArgs().Len() == 0 {
return name
}
args := make([]string, 0, t.TypeArgs().Len())
for i := 0; i < t.TypeArgs().Len(); i++ {
arg := t.TypeArgs().At(i)
args = append(args, g.renderType(ctx, arg))
}
return fmt.Sprintf("%s[%s]", name, strings.Join(args, ","))
}

func (g *Generator) renderType(ctx context.Context, typ types.Type) string {
switch t := typ.(type) {
case *types.Named:
name := g.getPackageScopedType(ctx, t.Obj())
if t.TypeArgs() == nil || t.TypeArgs().Len() == 0 {
return name
}
args := make([]string, 0, t.TypeArgs().Len())
for i := 0; i < t.TypeArgs().Len(); i++ {
arg := t.TypeArgs().At(i)
args = append(args, g.renderType(ctx, arg))
}
return fmt.Sprintf("%s[%s]", name, strings.Join(args, ","))
return g.renderNamedType(ctx, t)
case *types.Alias:
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm actually surprised that CI/CD is not failing in the go1.21 test. This didn't exist until 1.22 so technically this won't compile if someone tries to build with 1.21.

If I'm understanding that correctly, we will need to make sure people understand. But I'd also like to figure out why CICD didn't fail.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I see, go will download at least 1.22 because of our go.mod

$ /opt/homebrew/opt/go@1.21/bin/go version
go: downloading go1.22.0 (darwin/arm64)
go version go1.22.0 darwin/arm64

Also 1.21 is not supported anymore anyways, so we can probably remove it from the matrix and figure out how to get 1.23 to work in the test matrix.

Warning: go@1.21 has been deprecated because it is not supported upstream! It will be disabled on 2025-08-16.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I did a CI test with go 1.23 enabled, but it requires the lastest golangci-lint, but installing it forces the library's go.mod to go 1.23.

return g.renderNamedType(ctx, t)
case *types.TypeParam:
if t.Constraint() != nil {
name := t.Obj().Name()
Expand Down
59 changes: 59 additions & 0 deletions pkg/generator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -815,3 +815,62 @@ func TestParseReplaceType(t *testing.T) {
assert.Equal(t, test.expected, *actual)
}
}


func (s *GeneratorSuite) TestReplaceTypePackagePrologueGo123() {
expected := `package mocks

import baz "github.com/vektra/mockery/v2/pkg/fixtures/example_project/baz"
import mock "github.com/stretchr/testify/mock"

`
generator := NewGenerator(
s.ctx,
GeneratorConfig{InPackage: false},
s.getInterfaceFromFile("example_project/baz/foo.go", "Foo"),
pkg,
)

s.checkPrologueGeneration(generator, expected)
}

func (s *GeneratorSuite) TestReplaceTypePackageGo123() {
cfg := GeneratorConfig{InPackage: false}

s.checkGenerationRegexWithConfig("example_project/baz/foo.go", "Foo", cfg, []regexpExpected{
// func (_m *Foo) GetBaz() (*baz.Baz, error)
{true, regexp.MustCompile(`func \([^\)]+\) GetBaz\(\) \(\*baz\.Baz`)},
// func (_m *Foo) GetBaz() (*foo.InternalBaz, error)
{false, regexp.MustCompile(`func \([^\)]+\) GetBaz\(\) \(\*foo\.InternalBaz`)},
})
}

func (s *GeneratorSuite) TestReplaceTypePackageMultiplePrologueGo123() {
expected := `package mocks

import mock "github.com/stretchr/testify/mock"
import replace_type "github.com/vektra/mockery/v2/pkg/fixtures/example_project/replace_type"
import rt1 "github.com/vektra/mockery/v2/pkg/fixtures/example_project/replace_type/rti/rt1"
import rt2 "github.com/vektra/mockery/v2/pkg/fixtures/example_project/replace_type/rti/rt2"

`
generator := NewGenerator(
s.ctx,
GeneratorConfig{InPackage: false},
s.getInterfaceFromFile("example_project/replace_type/rt.go", "RType"),
pkg,
)

s.checkPrologueGeneration(generator, expected)
}

func (s *GeneratorSuite) TestReplaceTypePackageMultipleGo123() {
cfg := GeneratorConfig{InPackage: false}

s.checkGenerationRegexWithConfig("example_project/replace_type/rt.go", "RType", cfg, []regexpExpected{
// func (_m *RType) Replace1(f rt1.RType1)
{true, regexp.MustCompile(`func \([^\)]+\) Replace1\(f rt1\.RType1`)},
// func (_m *RType) Replace2(f rt2.RType2)
{true, regexp.MustCompile(`func \([^\)]+\) Replace2\(f rt2\.RType2`)},
})
}
2 changes: 1 addition & 1 deletion pkg/logging/logging.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ func GetLogger(levelStr string) (zerolog.Logger, error) {
Out: out,
TimeFormat: time.RFC822,
}
if !term.IsTerminal(int(out.Fd())) || os.Getenv("TERM") == "dumb" {
if !term.IsTerminal(int(out.Fd())) || os.Getenv("TERM") == "dumb" { //nolint:gosec
writer.NoColor = true
}
log := zerolog.New(writer).
Expand Down
Loading
Loading