From 14a9cc6248367025a6496bc86e7ba3dbdcbf4f12 Mon Sep 17 00:00:00 2001 From: Alex Date: Sat, 1 Feb 2025 00:01:28 +0300 Subject: [PATCH] feat: Error message for nonexistent mocks (#907) feat: warn message for nonexistent mocks --- .gitignore | 1 + .mockery.yaml | 3 +++ cmd/mockery.go | 29 +++++++++++++++++++++++++---- go.work.sum | 4 ++++ pkg/config/config.go | 5 ++--- pkg/parse.go | 21 ++++++++++++++++++++- 6 files changed, 55 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index ce357ea3..5544cdcd 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ coverage.txt site/ .task/ tools/tools +*.lua diff --git a/.mockery.yaml b/.mockery.yaml index 55839dae..d8fa0d8b 100644 --- a/.mockery.yaml +++ b/.mockery.yaml @@ -127,3 +127,6 @@ packages: mockname: Interface2WithUnresolvedAlias - resolve-type-alias: True mockname: Interface2WithResolvedAlias + github.com/vektra/mockery/v2/pkg/: + interfaces: + InterfaceDoesntExist: diff --git a/cmd/mockery.go b/cmd/mockery.go index 107997c0..a911252d 100644 --- a/cmd/mockery.go +++ b/cmd/mockery.go @@ -10,15 +10,16 @@ import ( "runtime/pprof" "strings" + "github.com/vektra/mockery/v2/pkg" + "github.com/vektra/mockery/v2/pkg/config" + "github.com/vektra/mockery/v2/pkg/logging" + "github.com/vektra/mockery/v2/pkg/stackerr" + "github.com/chigopher/pathlib" "github.com/mitchellh/go-homedir" "github.com/rs/zerolog/log" "github.com/spf13/cobra" "github.com/spf13/viper" - "github.com/vektra/mockery/v2/pkg" - "github.com/vektra/mockery/v2/pkg/config" - "github.com/vektra/mockery/v2/pkg/logging" - "github.com/vektra/mockery/v2/pkg/stackerr" "golang.org/x/tools/go/packages" ) @@ -258,6 +259,7 @@ func (r *RootApp) Run() error { log.Error().Err(err).Msg("unable to parse packages") return err } + log.Info().Msg("done loading, visiting interface nodes") for _, iface := range parser.Interfaces() { ifaceLog := log. @@ -284,6 +286,25 @@ func (r *RootApp) Run() error { } } + // Output interfaces that were specified but not found. + // We do that here and not before the loop because it's easier to + // see for the user. + for _, p := range configuredPackages { + ifaceList, err := r.Config.GetInterfacesForPackage(ctx, p) + if err != nil { + log.Error().Msgf("Failed to get interfaces for package %s: %v", p, err) + } + + for _, name := range ifaceList { + if !parser.Has(p, name) { + log.Warn().Ctx(ctx). + Str(logging.LogKeyInterface, name). + Str(logging.LogKeyQualifiedName, p). + Msg("no such interface") + } + } + } + return nil } diff --git a/go.work.sum b/go.work.sum index aeec4354..30caaa88 100644 --- a/go.work.sum +++ b/go.work.sum @@ -693,6 +693,7 @@ github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI= github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= github.com/census-instrumentation/opencensus-proto v0.3.0 h1:t/LhUZLVitR1Ow2YOnduCsavhwFUklBMoGVYUCqmCqk= github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMrBo8f1j86j5WHzznCCQxV/b8g= @@ -1163,6 +1164,7 @@ golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= +golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM= golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= @@ -1191,6 +1193,7 @@ golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1229,6 +1232,7 @@ golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/telemetry v0.0.0-20240521205824-bda55230c457 h1:zf5N6UOrA487eEFacMePxjXAJctxKmyjKUsjA11Uzuk= golang.org/x/telemetry v0.0.0-20240521205824-bda55230c457/go.mod h1:pRgIJT+bRLFKnoM1ldnzKoxTIn14Yxz928LQRYYgIN0= golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw= diff --git a/pkg/config/config.go b/pkg/config/config.go index 21b1251b..77602f55 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -103,7 +103,6 @@ func NewConfigFromViper(v *viper.Viper) (*Config, error) { v.SetDefault("case", "camel") v.SetDefault("dir", ".") v.SetDefault("output", "./mocks") - } else { v.SetDefault("dir", "mocks/{{.PackagePath}}") v.SetDefault("filename", "mock_{{.InterfaceName}}.go") @@ -734,7 +733,7 @@ func (c *Config) mergeInConfig(ctx context.Context) error { configSectionTyped[key] = value } } - interfaces, err := c.getInterfacesForPackage(pkgCtx, pkgPath) + interfaces, err := c.GetInterfacesForPackage(pkgCtx, pkgPath) if err != nil { return fmt.Errorf("failed to get interfaces for package: %w", err) } @@ -777,7 +776,7 @@ func (c *Config) mergeInConfig(ctx context.Context) error { return nil } -func (c *Config) getInterfacesForPackage(ctx context.Context, pkgPath string) ([]string, error) { +func (c *Config) GetInterfacesForPackage(ctx context.Context, pkgPath string) ([]string, error) { interfaces := []string{} packageMap, err := c.getPackageConfigMap(ctx, pkgPath) if err != nil { diff --git a/pkg/parse.go b/pkg/parse.go index 235e286b..5ba8324b 100644 --- a/pkg/parse.go +++ b/pkg/parse.go @@ -11,8 +11,9 @@ import ( "sort" "strings" - "github.com/rs/zerolog" "github.com/vektra/mockery/v2/pkg/logging" + + "github.com/rs/zerolog" "golang.org/x/tools/go/packages" ) @@ -223,6 +224,24 @@ func (p *Parser) Find(name string) (*Interface, error) { return nil, ErrNotInterface } +func (p *Parser) Has(packageName, interfaceName string) bool { + for _, entry := range p.files { + if entry.pkg.PkgPath != packageName { + continue + } + + for _, ifaceName := range entry.interfaces { + if ifaceName != interfaceName { + continue + } + + return true + } + } + + return false +} + func (p *Parser) Interfaces() []*Interface { ifaces := make(sortableIFaceList, 0) for _, entry := range p.files {