Skip to content

Commit 3b47547

Browse files
authored
Merge pull request #1059 from LandonTClipp/LandonTClipp/interface_dir_relative
Fix issue with relative `dir` values causing invalid in-package calculation
2 parents 64cdffa + 9022f5a commit 3b47547

File tree

9 files changed

+166
-45
lines changed

9 files changed

+166
-45
lines changed

.mockery_testify.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ template-data:
1212
boilerplate-file: "./.boilerplate.txt"
1313
packages:
1414
github.com/vektra/mockery/v3/internal/cmd:
15+
github.com/vektra/mockery/v3:
16+
config:
17+
dir: .
1518
github.com/vektra/mockery/v3/internal/fixtures/unexported:
1619
github.com/vektra/mockery/v3/internal/fixtures/buildtag/comment:
1720
github.com/vektra/mockery/v3/internal/fixtures/example_project/replace_type:

config/config.go

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -577,44 +577,53 @@ var ErrInfiniteLoop = fmt.Errorf("infinite loop in template variables detected")
577577
// interface being mocked. If this argument is nil, interface-specific template
578578
// variables will be set to the empty string. The srcPkg is also needed to
579579
// satisfy template variables regarding the source package.
580-
func (c *Config) ParseTemplates(ctx context.Context, ifaceFileName string, ifaceName string, srcPkg *packages.Package) error {
580+
func (c *Config) ParseTemplates(
581+
ctx context.Context,
582+
// ifaceFilePath is the absolute path of the original interface.
583+
ifaceFilePath string,
584+
ifaceName string,
585+
srcPkg *packages.Package,
586+
) error {
581587
log := zerolog.Ctx(ctx)
582588

583589
mock := "mock"
584590
if ast.IsExported(ifaceName) {
585591
mock = "Mock"
586592
}
587593

588-
var (
589-
interfaceDir string
590-
interfaceDirRelative string
591-
interfaceFile string
592-
interfaceName string
593-
)
594-
interfaceFile = ifaceFileName
595-
interfaceName = ifaceName
596-
597594
workingDir, err := os.Getwd()
598595
if err != nil {
599596
return fmt.Errorf("get working directory: %w", err)
600597
}
601-
interfaceDirPath := pathlib.NewPath(ifaceFileName).Parent()
602-
interfaceDir = interfaceDirPath.String()
598+
interfaceDirPath := pathlib.NewPath(ifaceFilePath).Parent()
603599
interfaceDirRelativePath, err := interfaceDirPath.RelativeToStr(workingDir)
600+
601+
var interfaceDirRelative string
602+
604603
if err != nil {
605-
log.Debug().Err(err).Msg("can't make path relative to working dir, setting to './'")
604+
log.Debug().
605+
Err(err).
606+
Str("working-dir", workingDir).
607+
Str("interfaceDirPath", interfaceDirPath.String()).
608+
Str("interface-dir-relative-path", interfaceDirRelativePath.String()).
609+
Msg("can't make path relative to working dir, setting to './'")
606610
interfaceDirRelative = "."
607611
} else {
612+
log.Debug().
613+
Str("working-dir", workingDir).
614+
Str("interfaceDirPath", interfaceDirPath.String()).
615+
Str("interface-dir-relative-path", interfaceDirRelativePath.String()).
616+
Msg("found relative path")
608617
interfaceDirRelative = interfaceDirRelativePath.String()
609618
}
610619

611620
// data is the struct sent to the template parser
612621
data := TemplateData{
613622
ConfigDir: filepath.Dir(*c.ConfigFile),
614-
InterfaceDir: interfaceDir,
623+
InterfaceDir: interfaceDirPath.String(),
615624
InterfaceDirRelative: interfaceDirRelative,
616-
InterfaceFile: interfaceFile,
617-
InterfaceName: interfaceName,
625+
InterfaceFile: ifaceFilePath,
626+
InterfaceName: ifaceName,
618627
Mock: mock,
619628
StructName: *c.StructName,
620629
SrcPackageName: srcPkg.Types.Name(),

foo.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package main
2+
3+
type baz string
4+
5+
type foo interface {
6+
Bar() baz
7+
}

foo_test.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package main
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
)
8+
9+
func TestFoo(t *testing.T) {
10+
m := newMockfoo(t)
11+
m.EXPECT().Bar().Return(baz("foo"))
12+
assert.Equal(t, "foo", m.Bar())
13+
}

internal/cmd/mockery.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ func (r *RootApp) Run() error {
263263
}
264264
ifaceConfig := pkgConfig.GetInterfaceConfig(ctx, iface.Name)
265265
for _, ifaceConfig := range ifaceConfig.Configs {
266-
if err := ifaceConfig.ParseTemplates(ifaceCtx, iface.FileName, iface.Name, iface.Pkg); err != nil {
266+
if err := ifaceConfig.ParseTemplates(ifaceCtx, iface.FilePath, iface.Name, iface.Pkg); err != nil {
267267
log.Err(err).Msg("Can't parse config templates for interface")
268268
return err
269269
}
@@ -279,15 +279,16 @@ func (r *RootApp) Run() error {
279279
*ifaceConfig.PkgName,
280280
*ifaceConfig.Template,
281281
)
282+
log.Debug().Str("file-path", filePath.String()).Msg("creating new interface collection")
282283
}
283284
if err := mockFileToInterfaces[filePath.String()].Append(
284285
ctx,
285286
internal.NewInterface(
286287
iface.Name,
287288
iface.TypeSpec,
288289
iface.GenDecl,
289-
iface.FileName,
290-
iface.File,
290+
iface.FilePath,
291+
iface.FileSyntax,
291292
iface.Pkg,
292293
ifaceConfig),
293294
); err != nil {

internal/interface.go

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,31 +8,31 @@ import (
88
)
99

1010
type Interface struct {
11-
Name string // Name of the type to be mocked.
12-
TypeSpec *ast.TypeSpec
13-
GenDecl *ast.GenDecl
14-
FileName string
15-
File *ast.File
16-
Pkg *packages.Package
17-
Config *config.Config
11+
Name string // Name of the type to be mocked.
12+
TypeSpec *ast.TypeSpec
13+
GenDecl *ast.GenDecl
14+
FilePath string
15+
FileSyntax *ast.File
16+
Pkg *packages.Package
17+
Config *config.Config
1818
}
1919

2020
func NewInterface(
2121
name string,
2222
typeSpec *ast.TypeSpec,
2323
genDecl *ast.GenDecl,
24-
filename string,
25-
file *ast.File,
24+
filepath string,
25+
fileSyntax *ast.File,
2626
pkg *packages.Package,
2727
config *config.Config,
2828
) *Interface {
2929
return &Interface{
30-
Name: name,
31-
TypeSpec: typeSpec,
32-
GenDecl: genDecl,
33-
FileName: filename,
34-
File: file,
35-
Pkg: pkg,
36-
Config: config,
30+
Name: name,
31+
TypeSpec: typeSpec,
32+
GenDecl: genDecl,
33+
FilePath: filepath,
34+
FileSyntax: fileSyntax,
35+
Pkg: pkg,
36+
Config: config,
3737
}
3838
}

internal/parse.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,10 @@ func (p *Parser) ParsePackages(ctx context.Context, packageNames []string) ([]*I
6666
if len(pkg.Errors) != 0 {
6767
return nil, errors.New("error occurred when loading packages")
6868
}
69-
for fileIdx, file := range pkg.GoFiles {
70-
fileLog := pkgLog.With().Str("file", file).Logger()
69+
for fileIdx, filePath := range pkg.GoFiles {
70+
fileLog := pkgLog.With().Str("file", filePath).Logger()
7171
fileLog.Debug().Msg("found file")
72-
isGenerated, err := isAutoGenerated(pathlib.NewPath(file))
72+
isGenerated, err := isAutoGenerated(pathlib.NewPath(filePath))
7373
if err != nil {
7474
return nil, fmt.Errorf("determining if file is auto-generated: %w", err)
7575
}
@@ -115,7 +115,7 @@ func (p *Parser) ParsePackages(ctx context.Context, packageNames []string) ([]*I
115115
name,
116116
declaredInterface.typeSpec,
117117
declaredInterface.genDecl,
118-
file,
118+
filePath,
119119
fileSyntax,
120120
pkg,
121121
// Leave the config nil because we don't yet know if

internal/template_generator.go

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -135,13 +135,9 @@ func NewTemplateGenerator(
135135
pkgConfig *config.Config,
136136
pkgName string,
137137
) (*TemplateGenerator, error) {
138+
log := *zerolog.Ctx(ctx)
139+
138140
srcPkgFSPath := pathlib.NewPath(srcPkg.GoFiles[0]).Parent()
139-
log := zerolog.Ctx(ctx).With().
140-
Stringer("srcPkgFSPath", srcPkgFSPath).
141-
Stringer("outPkgFSPath", outPkgFSPath).
142-
Str("src-pkg-name", srcPkg.Name).
143-
Str("out-pkg-name", pkgName).
144-
Logger()
145141
if !outPkgFSPath.IsAbsolute() {
146142
cwd, err := os.Getwd()
147143
if err != nil {
@@ -150,6 +146,17 @@ func NewTemplateGenerator(
150146
}
151147
outPkgFSPath = pathlib.NewPath(cwd).JoinPath(outPkgFSPath)
152148
}
149+
srcPkgFSPath = srcPkgFSPath.Clean()
150+
outPkgFSPath = outPkgFSPath.Clean()
151+
152+
newLogger := zerolog.Ctx(ctx).With().
153+
Stringer("srcPkgFSPath", srcPkgFSPath).
154+
Stringer("outPkgFSPath", outPkgFSPath).
155+
Str("src-pkg-name", srcPkg.Name).
156+
Str("out-pkg-name", pkgName).
157+
Logger()
158+
log = newLogger
159+
153160
outPkgPath, err := findPkgPath(outPkgFSPath)
154161
if err != nil {
155162
log.Err(err).Msg("failed to find output package path")

mocks_testify_main_test.go

Lines changed: 81 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)