Skip to content

Commit

Permalink
Fix issues with merging
Browse files Browse the repository at this point in the history
  • Loading branch information
LandonTClipp committed Jan 6, 2025
1 parent 55ba9bb commit 95cf7ed
Show file tree
Hide file tree
Showing 25 changed files with 4,061 additions and 156 deletions.
2 changes: 2 additions & 0 deletions .mockery.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ dir: "{{.InterfaceDir}}"
mockname: "Mock{{.InterfaceName}}"
pkgname: "{{.SrcPackageName}}"
filename: "mocks_test.go"
boilerplate-file: "./.boilerplate.txt"
packages:
github.com/vektra/mockery/v3/internal/fixtures/buildtag/comment:
github.com/vektra/mockery/v3/internal/fixtures:
Expand Down Expand Up @@ -40,3 +41,4 @@ packages:
github.com/vektra/mockery/v3/internal/fixtures/index_list_expr:
github.com/vektra/mockery/v3/internal/fixtures/iface_new_type:
github.com/vektra/mockery/v3/internal/fixtures/type_alias:

10 changes: 0 additions & 10 deletions .mockery_moq.yaml

This file was deleted.

11 changes: 11 additions & 0 deletions .mockery_moq.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
template: moq
boilerplate-file: "./.boilerplate.txt"
mockname: "Moq{{.InterfaceName}}"
filename: "mocks_moq_test.go"
all: true
packages:
github.com/vektra/mockery/v3/internal/fixtures:
config:
all: false
include-regex: '.*'
exclude-regex: 'RequesterGenerics'
2 changes: 1 addition & 1 deletion docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ Parameter Descriptions
| `boilerplate-file` | :fontawesome-solid-x: | `#!yaml ""` | Specify a path to a file that contains comments you want displayed at the top of all generated mock files. This is commonly used to display license headers at the top of your source code. |
| `config` | :fontawesome-solid-x: | `#!yaml ""` | Set the location of the mockery config file. |
| `dir` | :fontawesome-solid-check: | `#!yaml "mocks/{{.SrcPackagePath}}"` | The directory where the mock file will be outputted to. |
| `exclude` | :fontawesome-solid-x: | `#!yaml []` | Specify subpackages to exclude when using `#!yaml recursive: True` |
| `exclude-subpkg-regex` | :fontawesome-solid-x: | `#!yaml []` | A list of regular expressions that denote which subpackages should be excluded when `#!yaml recursive: true` |
| `exclude-regex` | :fontawesome-solid-x: | `#!yaml ""` | When set along with `include-regex`, then interfaces which match `include-regex` but also match `exclude-regex` will not be generated. If `all` is set, or if `include-regex` is not set, then `exclude-regex` has no effect. |
| `filename` | :fontawesome-solid-check: | `#!yaml "mock_{{.InterfaceName}}.go"` | The name of the file the mock will reside in. |
| `formatter` | :fontawesome-solid-x: | `#!yaml "goimports"` | The formatter to use on the rendered template. Choices are: `gofmt`, `goimports`, `noop`. |
Expand Down
32 changes: 16 additions & 16 deletions internal/cmd/mockery.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,27 +148,27 @@ func (i *InterfaceCollection) Append(ctx context.Context, iface *pkg.Interface)
Str("source-pkgname", iface.Pkg.Name).
Str(logging.LogKeyPackagePath, iface.Pkg.PkgPath).
Str("expected-package-path", i.srcPkgPath).Logger()
if i.outFilePath.String() != pathlib.NewPath(iface.Config.Dir).Join(iface.Config.FileName).String() {
if i.outFilePath.String() != pathlib.NewPath(*iface.Config.Dir).Join(*iface.Config.FileName).String() {
msg := "all mocks in an InterfaceCollection must have the same output file path"
log.Error().Msg(msg)
return errors.New(msg)
}
if i.outPkgName != iface.Config.PkgName {
if i.outPkgName != *iface.Config.PkgName {
msg := "all mocks in an output file must have the same pkgname"
log.Error().Str("output-pkgname", i.outPkgName).Str("interface-pkgname", iface.Config.PkgName).Msg(msg)
log.Error().Str("output-pkgname", i.outPkgName).Str("interface-pkgname", *iface.Config.PkgName).Msg(msg)
return errors.New(msg)
}
if i.template != iface.Config.Template {
if i.template != *iface.Config.Template {
msg := "all mocks in an output file must use the same template"
log.Error().Str("expected-template", i.template).Str("interface-template", iface.Config.Template).Msg(msg)
log.Error().Str("expected-template", i.template).Str("interface-template", *iface.Config.Template).Msg(msg)
return errors.New(msg)
}
i.interfaces = append(i.interfaces, iface)
return nil
}

func (r *RootApp) Run() error {
log, err := logging.GetLogger(r.Config.LogLevel)
log, err := logging.GetLogger(*r.Config.LogLevel)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to initialize logger: %v\n", err)
return err
Expand All @@ -180,7 +180,7 @@ func (r *RootApp) Run() error {
return err
}

buildTags := strings.Split(r.Config.BuildTags, " ")
buildTags := strings.Split(*r.Config.BuildTags, " ")

configuredPackages, err := r.Config.GetPackages(ctx)
if err != nil {
Expand Down Expand Up @@ -220,14 +220,14 @@ func (r *RootApp) Run() error {
if err != nil {
return fmt.Errorf("getting package %s: %w", iface.Pkg.PkgPath, err)
}
ifaceLog.Debug().Str("root-mock-name", r.Config.Config.MockName).Str("pkg-mock-name", pkgConfig.Config.MockName).Msg("mock-name during first GetPackageConfig")
ifaceLog.Debug().Str("root-mock-name", *r.Config.Config.MockName).Str("pkg-mock-name", *pkgConfig.Config.MockName).Msg("mock-name during first GetPackageConfig")

shouldGenerate, err := pkgConfig.ShouldGenerateInterface(ifaceCtx, iface.Name)
if err != nil {
return err
}
if !shouldGenerate {
ifaceLog.Debug().Msg("config doesn't specify to generate this interface, skipping.")
ifaceLog.Debug().Msg("config doesn't specify to generate this interface, skipping")
continue
}
ifaceLog.Info().Msg("adding interface")
Expand All @@ -248,10 +248,10 @@ func (r *RootApp) Run() error {
if !ok {
mockFileToInterfaces[filePath] = NewInterfaceCollection(
iface.Pkg.PkgPath,
pathlib.NewPath(ifaceConfig.Dir).Join(ifaceConfig.FileName),
pathlib.NewPath(*ifaceConfig.Dir).Join(*ifaceConfig.FileName),
iface.Pkg,
ifaceConfig.PkgName,
ifaceConfig.Template,
*ifaceConfig.PkgName,
*ifaceConfig.Template,
)
}
if err := mockFileToInterfaces[filePath].Append(
Expand All @@ -278,18 +278,18 @@ func (r *RootApp) Run() error {
if err != nil {
return err
}
fileLog.Debug().Str("mock-name", packageConfig.Config.MockName).Msg("package config mockname before parsing")
fileLog.Debug().Str("mock-name", *packageConfig.Config.MockName).Msg("package config mockname before parsing")
if err := packageConfig.Config.ParseTemplates(ctx, nil, interfacesInFile.srcPkg); err != nil {
return err
}
fileLog.Debug().Str("mock-name", packageConfig.Config.MockName).Msg("package config mockname after parsing")
fileLog.Debug().Str("mock-name", *packageConfig.Config.MockName).Msg("package config mockname after parsing")

generator, err := pkg.NewTemplateGenerator(
fileCtx,
interfacesInFile.interfaces[0].Pkg,
interfacesInFile.outFilePath.Parent(),
packageConfig.Config.Template,
pkg.Formatter(r.Config.Formatter),
*packageConfig.Config.Template,
pkg.Formatter(*r.Config.Formatter),
packageConfig.Config,
interfacesInFile.outPkgName,
)
Expand Down
3 changes: 2 additions & 1 deletion internal/cmd/showconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@ func NewShowConfigCmd() *cobra.Command {
if err != nil {
return err
}

ctx := log.WithContext(context.Background())
conf, _, err := pkg.NewRootConfig(ctx, nil, nil)
conf, _, err := pkg.NewRootConfig(ctx, nil, cmd.Parent().PersistentFlags())
if err != nil {
return err
}
Expand Down
134 changes: 87 additions & 47 deletions internal/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,34 @@ func NewRootConfig(
) (*RootConfig, *koanf.Koanf, error) {
log := zerolog.Ctx(ctx)
var err error
var rootConfig RootConfig = RootConfig{
Config: &Config{
Dir: "{{.InterfaceDir}}",
FileName: "mocks_test.go",
Formatter: "goimports",
MockName: "Mock{{.InterfaceName}}",
PkgName: "{{.SrcPackageName}}",
LogLevel: "info",
},
strPtr := func(s string) *string {
return &s
}
defaultConfig := &Config{
Dir: strPtr("{{.InterfaceDir}}"),
FileName: strPtr("mocks_test.go"),
Formatter: strPtr("goimports"),
MockName: strPtr("Mock{{.InterfaceName}}"),
PkgName: strPtr("{{.SrcPackageName}}"),
LogLevel: strPtr("info"),
}
// Set all the other parameters to their respective zero-values. Need to use
// reflection for this sadly.
v := reflect.ValueOf(defaultConfig).Elem()
for i := 0; i < v.NumField(); i++ {
field := v.Field(i)
if field.Kind() != reflect.Pointer {
continue
}
if !field.IsNil() {
continue
}
field.Set(reflect.New(field.Type().Elem()))
}

var rootConfig RootConfig = RootConfig{
Config: defaultConfig,
}
k := koanf.New("|")
rootConfig.koanf = k
if configFile != nil {
Expand All @@ -66,6 +83,13 @@ func NewRootConfig(
configFile = pathlib.NewPath(configFileFromEnv)
}
}
if configFile == nil {
configFileFromFlags, err := flags.GetString("config")
if err != nil {
return nil, nil, fmt.Errorf("getting --config from flags: %w", err)
}
configFile = pathlib.NewPath(configFileFromFlags)
}
if configFile == nil {
log.Debug().Msg("config file not specified, searching")
configFile, err = findConfig()
Expand Down Expand Up @@ -156,8 +180,12 @@ func (c *RootConfig) Initialize(ctx context.Context) error {
if err := pkgConfig.Initialize(pkgCtx); err != nil {
return fmt.Errorf("initializing root config: %w", err)
}
if pkgConfig.Config.Recursive {
recursivePackages = append(recursivePackages, pkgName)
if *pkgConfig.Config.Recursive {
if !c.ShouldExcludeSubpkg(pkgName) {
recursivePackages = append(recursivePackages, pkgName)
} else {
pkgLog.Debug().Msg("package was marked for exclusion")
}
}
}

Expand Down Expand Up @@ -274,22 +302,23 @@ func (c PackageConfig) GetInterfaceConfig(ctx context.Context, interfaceName str

func (c PackageConfig) ShouldGenerateInterface(ctx context.Context, interfaceName string) (bool, error) {
log := zerolog.Ctx(ctx)
if c.Config.All {
if c.Config.IncludeRegex != "" {
if *c.Config.All {
if *c.Config.IncludeRegex != "" {
log.Warn().Msg("interface config has both `all` and `include-regex` set: `include-regex` will be ignored")
}
if c.Config.ExcludeRegex != "" {
if *c.Config.ExcludeRegex != "" {
log.Warn().Msg("interface config has both `all` and `exclude-regex` set: `exclude-regex` will be ignored")
}
log.Debug().Msg("`all: true` is set, interface should be generated")
return true, nil
}

if _, exists := c.Interfaces[interfaceName]; exists {
return true, nil
}

includeRegex := c.Config.IncludeRegex
excludeRegex := c.Config.ExcludeRegex
includeRegex := *c.Config.IncludeRegex
excludeRegex := *c.Config.ExcludeRegex
if includeRegex == "" {
if excludeRegex != "" {
log.Warn().Msg("interface config has `exclude-regex` set but not `include-regex`: `exclude-regex` will be ignored")
Expand All @@ -301,16 +330,23 @@ func (c PackageConfig) ShouldGenerateInterface(ctx context.Context, interfaceNam
return false, fmt.Errorf("evaluating `include-regex`: %w", err)
}
if !includedByRegex {
log.Debug().Msg("interface does not match include-regex")
return false, nil
}
log.Debug().Msg("interface matches include-regex")
if excludeRegex == "" {
return true, nil
}
excludedByRegex, err := regexp.MatchString(excludeRegex, interfaceName)
if err != nil {
return false, fmt.Errorf("evaluating `exclude-regex`: %w", err)
}
return !excludedByRegex, nil
if excludedByRegex {
log.Debug().Msg("interface matches exclude-regex")
return false, nil
}
log.Debug().Msg("interface does not match exclude-regex")
return true, nil
}

type InterfaceConfig struct {
Expand Down Expand Up @@ -338,26 +374,26 @@ func (c *InterfaceConfig) Initialize(ctx context.Context) error {
}

type Config struct {
All bool `koanf:"all"`
Anchors map[string]any `koanf:"_anchors"`
BoilerplateFile string `koanf:"boilerplate-file"`
BuildTags string `koanf:"tags"`
ConfigFile string `koanf:"config"`
Dir string `koanf:"dir"`
Exclude []string `koanf:"exclude"`
ExcludeRegex string `koanf:"exclude-regex"`
FileName string `koanf:"filename"`
Formatter string `koanf:"formatter"`
IncludeRegex string `koanf:"include-regex"`
LogLevel string `koanf:"log-level"`
MockBuildTags string `koanf:"mock-build-tags"`
MockName string `koanf:"mockname"`
PkgName string `koanf:"pkgname"`
Recursive bool `koanf:"recursive"`
Template string `koanf:"template"`
TemplateData map[string]any `koanf:"template-data"`
UnrollVariadic bool `koanf:"unroll-variadic"`
Version bool `koanf:"version"`
All *bool `koanf:"all"`
Anchors map[string]any `koanf:"_anchors"`
BoilerplateFile *string `koanf:"boilerplate-file"`
BuildTags *string `koanf:"tags"`
ConfigFile *string `koanf:"config"`
Dir *string `koanf:"dir"`
ExcludeSubpkgRegex []string `koanf:"exclude-subpkg-regex"`
ExcludeRegex *string `koanf:"exclude-regex"`
FileName *string `koanf:"filename"`
Formatter *string `koanf:"formatter"`
IncludeRegex *string `koanf:"include-regex"`
LogLevel *string `koanf:"log-level"`
MockBuildTags *string `koanf:"mock-build-tags"`
MockName *string `koanf:"mockname"`
PkgName *string `koanf:"pkgname"`
Recursive *bool `koanf:"recursive"`
Template *string `koanf:"template"`
TemplateData map[string]any `koanf:"template-data"`
UnrollVariadic *bool `koanf:"unroll-variadic"`
Version *bool `koanf:"version"`
}

func findConfig() (*pathlib.Path, error) {
Expand All @@ -383,12 +419,16 @@ func findConfig() (*pathlib.Path, error) {
}

func (c *Config) FilePath() *pathlib.Path {
return pathlib.NewPath(c.Dir).Join(c.FileName)
return pathlib.NewPath(*c.Dir).Join(*c.FileName)
}

func (c *Config) ExcludePath(path string) bool {
for _, ex := range c.Exclude {
if strings.HasPrefix(path, ex) {
func (c *Config) ShouldExcludeSubpkg(pkgPath string) bool {
for _, regex := range c.ExcludeSubpkgRegex {
matched, err := regexp.MatchString(regex, pkgPath)
if err != nil {
panic(err)
}
if matched {
return true
}
}
Expand Down Expand Up @@ -457,24 +497,24 @@ func (c *Config) ParseTemplates(ctx context.Context, iface *Interface, srcPkg *p
}
// data is the struct sent to the template parser
data := mockeryTemplate.ConfigData{
ConfigDir: filepath.Dir(c.ConfigFile),
ConfigDir: filepath.Dir(*c.ConfigFile),
InterfaceDir: interfaceDir,
InterfaceDirRelative: interfaceDirRelative,
InterfaceFile: interfaceFile,
InterfaceName: interfaceName,
Mock: mock,
MockName: c.MockName,
MockName: *c.MockName,
SrcPackageName: srcPkg.Types.Name(),
SrcPackagePath: srcPkg.Types.Path(),
}
// These are the config options that we allow
// to be parsed by the templater. The keys are
// just labels we're using for logs/errors
templateMap := map[string]*string{
"filename": &c.FileName,
"dir": &c.Dir,
"mockname": &c.MockName,
"pkgname": &c.PkgName,
"filename": c.FileName,
"dir": c.Dir,
"mockname": c.MockName,
"pkgname": c.PkgName,
}

changesMade := true
Expand Down
1 change: 1 addition & 0 deletions internal/fixtures/buildtag/comment/mocks_test.go

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

1 change: 1 addition & 0 deletions internal/fixtures/empty_return/mocks_test.go

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

1 change: 1 addition & 0 deletions internal/fixtures/example_project/mocks_test.go

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

Loading

0 comments on commit 95cf7ed

Please sign in to comment.