Skip to content

Commit

Permalink
Fix issues with in-package detection and name conflict resolution
Browse files Browse the repository at this point in the history
  • Loading branch information
LandonTClipp committed Jan 1, 2025
1 parent 4bbd9d2 commit ce0236e
Show file tree
Hide file tree
Showing 11 changed files with 187 additions and 165 deletions.
31 changes: 9 additions & 22 deletions cmd/mockery.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,21 +171,18 @@ func GetRootAppFromViper(v *viper.Viper) (*RootApp, error) {
// uniform.
type InterfaceCollection struct {
srcPkgPath string
outPkgPath string
outFilePath *pathlib.Path
srcPkg *packages.Package
interfaces []*pkg.Interface
}

func NewInterfaceCollection(
srcPkgPath string,
outPkgPath string,
outFilePath *pathlib.Path,
srcPkg *packages.Package,
) *InterfaceCollection {
return &InterfaceCollection{
srcPkgPath: srcPkgPath,
outPkgPath: outPkgPath,
outFilePath: outFilePath,
srcPkg: srcPkg,
interfaces: make([]*pkg.Interface, 0),
Expand All @@ -208,15 +205,6 @@ func (i *InterfaceCollection) Append(ctx context.Context, iface *pkg.Interface)
log.Error().Msg(msg)
return errors.New(msg)
}
ifacePkgPath, err := iface.Config.PkgPath()
if err != nil {
return err
}
if ifacePkgPath != i.outPkgPath {
msg := "all mocks within an InterfaceCollection must have the same output package path"
log.Error().Msg(msg)
return errors.New(msg)
}
i.interfaces = append(i.interfaces, iface)
return nil
}
Expand Down Expand Up @@ -293,16 +281,11 @@ func (r *RootApp) Run() error {
return err
}
filePath := ifaceConfig.FilePath(ctx).String()
outPkgPath, err := ifaceConfig.PkgPath()
if err != nil {
return err
}

_, ok := mockFileToInterfaces[filePath]
if !ok {
mockFileToInterfaces[filePath] = NewInterfaceCollection(
iface.Pkg.PkgPath,
outPkgPath,
pathlib.NewPath(ifaceConfig.Dir).Join(ifaceConfig.FileName),
iface.Pkg,
)
Expand All @@ -324,8 +307,6 @@ func (r *RootApp) Run() error {
fileCtx := fileLog.WithContext(ctx)

fileLog.Debug().Int("interfaces-in-file-len", len(interfacesInFile.interfaces)).Msgf("%v", interfacesInFile)
outPkgPath := interfacesInFile.outPkgPath

packageConfig, err := r.Config.GetPackageConfig(fileCtx, interfacesInFile.srcPkgPath)
if err != nil {
return err
Expand All @@ -334,8 +315,9 @@ func (r *RootApp) Run() error {
return err
}
generator, err := pkg.NewTemplateGenerator(
fileCtx,
interfacesInFile.interfaces[0].Pkg,
outPkgPath,
interfacesInFile.outFilePath.Parent(),
packageConfig.Template,
pkg.Formatter(r.Config.Formatter),
packageConfig,
Expand All @@ -347,8 +329,13 @@ func (r *RootApp) Run() error {
if err != nil {
return err
}
if err := pathlib.NewPath(outFilePath).WriteFile(templateBytes); err != nil {
return err
outFile := pathlib.NewPath(outFilePath)
if err := outFile.Parent().MkdirAll(); err != nil {
log.Err(err).Msg("failed to mkdir parent directories of mock file")
return stackerr.NewStackErr(err)
}
if err := outFile.WriteFile(templateBytes); err != nil {
return stackerr.NewStackErr(err)
}
}

Expand Down
62 changes: 0 additions & 62 deletions pkg/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,6 @@ import (
"gopkg.in/yaml.v3"
)

var (
ErrNoConfigFile = fmt.Errorf("no config file exists")
ErrNoGoFilesFoundInRoot = fmt.Errorf("no go files found in root search path")
ErrPkgNotFound = fmt.Errorf("package not found in config")
ErrGoModNotFound = fmt.Errorf("no go.mod file found")
ErrGoModInvalid = fmt.Errorf("go.mod file has no module line")
)

type Config struct {
All bool `mapstructure:"all"`
Anchors map[string]any `mapstructure:"_anchors"`
Expand Down Expand Up @@ -927,60 +919,6 @@ func (c *Config) ParseTemplates(ctx context.Context, iface *Interface, srcPkg *p
return nil
}

// PkgPath returns the fully qualified package path of the output mock that this config
// represents. For example, it might return "github.com/vektra/mockery/v3/internal".
// This function will error if it cannot find a base go.mod file.
func (c *Config) PkgPath() (string, error) {
dirPath := pathlib.NewPath(c.Dir)
if err := dirPath.MkdirAll(); err != nil {
return "", stackerr.NewStackErr(err)
}
dir, err := pathlib.NewPath(c.Dir).ResolveAll()
if err != nil {
return "", stackerr.NewStackErr(err)
}
var goModFile *pathlib.Path
for i := 0; ; i++ {
if i == 1000 {
return "", stackerr.NewStackErr(errors.New("failed to find go.mod after 1000 iterations"))
}
goMod := dir.Join("go.mod")
goModExists, err := goMod.Exists()
if err != nil {
return "", stackerr.NewStackErr(err)
}
if !goModExists {
parent := dir.Parent()
// Hit the root path
if dir.String() == parent.String() {
return "", stackerr.NewStackErrf(
ErrGoModNotFound, "parsing package path for %s", c.Dir)
}
dir = parent
continue
}
goModFile = goMod
break
}
fileBytes, err := goModFile.ReadFile()
if err != nil {
return "", stackerr.NewStackErr(err)
}
scanner := bufio.NewScanner(bytes.NewReader(fileBytes))
// Iterate over each line
for scanner.Scan() {
if !strings.HasPrefix(scanner.Text(), "module") {
continue
}
moduleName := strings.Split(scanner.Text(), "module ")[1]
return pathlib.NewPath(
moduleName,
pathlib.PathWithSeperator("/")).
Join(c.Dir).String(), nil
}
return "", stackerr.NewStackErr(ErrGoModInvalid)
}

func (c *Config) ClearCfgAsMap() {
c._cfgAsMap = nil
}
11 changes: 11 additions & 0 deletions pkg/errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package pkg

import "fmt"

var (
ErrNoConfigFile = fmt.Errorf("no config file exists")
ErrNoGoFilesFoundInRoot = fmt.Errorf("no go files found in root search path")
ErrPkgNotFound = fmt.Errorf("package not found in config")
ErrGoModNotFound = fmt.Errorf("no go.mod file found")
ErrGoModInvalid = fmt.Errorf("go.mod file has no module line")
)
8 changes: 0 additions & 8 deletions pkg/fixtures/iface_new_type/iface_new_type_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,4 @@ func TestUsage(t *testing.T) {
interface1 := NewMockInterface1(t)
interface1.EXPECT().Method1().Return()
interface1.Method1()

interface2 := NewMockInterface2(t)
interface2.EXPECT().Method1().Return()
interface2.Method1()

interface3 := NewMockInterface3(t)
interface3.EXPECT().Method1().Return()
interface3.Method1()
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit ce0236e

Please sign in to comment.