Skip to content
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
4 changes: 2 additions & 2 deletions .github/workflows/documentation.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: documentation
on:
push:
branches: [ v3 ]
branches: [ master, v3 ]
permissions:
contents: write
jobs:
Expand All @@ -28,4 +28,4 @@ jobs:
- name: Deploy docs
run: "mike deploy --push --update-aliases $(grep VERSION mockery-tools.env | cut -d'=' -f 2 | cut -d'.' -f1-2) v3"
env:
GOOGLE_ANALYTICS_KEY: ${{ secrets.GOOGLE_ANALYTICS_KEY }}
GOOGLE_ANALYTICS_KEY: ${{ secrets.GOOGLE_ANALYTICS_KEY }}
2 changes: 1 addition & 1 deletion .github/workflows/reusable-testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
go-version: ${{ matrix.go_vers }}

- name: Download dependencies
run: go mod download
run: go mod download -x

- name: Test
run: go run github.com/go-task/task/v3/cmd/task test.ci
9 changes: 4 additions & 5 deletions .github/workflows/tag-and-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,11 @@ on:
permissions:
contents: write
jobs:
# TODO: temporarily disable testing during alpha development
#test:
# uses: ./.github/workflows/reusable-testing.yml
test:
uses: ./.github/workflows/reusable-testing.yml
tag:
runs-on: ubuntu-latest
#needs: test
needs: test
outputs:
tag_result: ${{ steps.tag.outputs.tag_result }}
requested_version: ${{ steps.tag.outputs.requested_version }}
Expand Down Expand Up @@ -96,4 +95,4 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GORELEASER_GITHUB_TOKEN }}
HOMEBREW_TAP_TOKEN: ${{ secrets.GORELEASER_HOMEBREW_TAP_TOKEN }}
GORELEASER_CURRENT_TAG: ${{ needs.tag.outputs.requested_version }}
#GORELEASER_PREVIOUS_TAG: ${{ needs.tag.outputs.previous_version }}
#GORELEASER_PREVIOUS_TAG: ${{ needs.tag.outputs.previous_version }}
2 changes: 1 addition & 1 deletion .github/workflows/testing-dispatch.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ jobs:
test:
uses: ./.github/workflows/reusable-testing.yml
with:
ref: ${{ inputs.ref }}
ref: ${{ inputs.ref }}
10 changes: 2 additions & 8 deletions .github/workflows/testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,8 @@ name: Go Test

on:
pull_request:
branches: [v3]
branches: [ master, v3 ]

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 0
- uses: ./.github/workflows/reusable-testing.yml

uses: ./.github/workflows/reusable-testing.yml
14 changes: 14 additions & 0 deletions .mockery.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,20 @@ template-data:
boilerplate-file: "./.boilerplate.txt"
packages:
github.com/vektra/mockery/v3/internal/fixtures/buildtag/comment:
github.com/vektra/mockery/v3/internal/fixtures/example_project/replace_type:
config:
recursive: True
interfaces:
RType:
configs:
- {}
- mockname: RTypeReplaced1
replace-type:
github.com/vektra/mockery/v3/internal/fixtures/example_project/replace_type/rti/rt1:
RType1:
pkg-path: github.com/vektra/mockery/v3/internal/fixtures/example_project/replace_type/rti/rt2
type-name: RType2

github.com/vektra/mockery/v3/internal/fixtures:
interfaces:
RequesterVariadic:
Expand Down
8 changes: 4 additions & 4 deletions Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ tasks:
sources:
- "**/*.go"
cmds:
- go fmt ./...
- gofumpt -l -w .

mocks:
desc: generate new mocks from scratch
Expand Down Expand Up @@ -83,11 +83,11 @@ tasks:
- ./e2e/run_all.sh

test.ci:
deps: [fmt, lint]
deps: [lint]
cmds:
- task: mocks.remove
- task: mocks.generate
- task: mocks
- task: test
- task: mocks.remove
- task: test.e2e

default:
Expand Down
15 changes: 15 additions & 0 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ Parameter Descriptions
| `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. |
| `force-file-write` | :fontawesome-solid-x: | `#!yaml false` | When set to `#!yaml force-file-write: true`, mockery will forcibly overwrite any existing files. |
| `formatter` | :fontawesome-solid-x: | `#!yaml "goimports"` | The formatter to use on the rendered template. Choices are: `gofmt`, `goimports`, `noop`. |
| `include-regex` | :fontawesome-solid-x: | `#!yaml ""` | When set, only interface names that match the expression will be generated. This setting is ignored if `all: True` is specified in the configuration. To further refine the interfaces generated, use `exclude-regex`. |
| `log-level` | :fontawesome-solid-x: | `#!yaml "info"` | Set the level of the logger |
Expand All @@ -65,11 +66,25 @@ Parameter Descriptions
| [`packages`](features.md#packages-configuration) | :fontawesome-solid-x: | `#!yaml null` | A dictionary containing configuration describing the packages and interfaces to generate mocks for. |
| `pkgname` | :fontawesome-solid-check: | `#!yaml "{{.SrcPackageName}}" | The `#!go package name` given to the generated mock files. |
| [`recursive`](features.md#recursive-package-discovery) | :fontawesome-solid-x: | `#!yaml false` | When set to `true` on a particular package, mockery will recursively search for all sub-packages and inject those packages into the config map. |
| [`replace-type`](replace-type.md) | :fontawesome-solid-x: | `#!yaml {}` | Use this parameter to specify type replacements. |
| `tags` | :fontawesome-solid-x: | `#!yaml ""` | A space-separated list of additional build tags to load packages. |
| `template` | :fontawesome-solid-x: | `#!yaml ""` | The template to use. The choices are `moq`, `mockery`, or a file path provided by `file://path/to/file.txt`. |
| `template-data` | :fontawesome-solid-x: | `#!yaml {}` | A `map[string]any` that provides arbitrary options to the template. Each template will have a different set of accepted keys. Refer to each template's documentation for more details. |


Config Templates
----------------

Parameters marked as being templated have access to a number of template variables and functions.

### Variables

The variables provided are specified in the [`ConfigData`](https://pkg.go.dev/github.com/vektra/mockery/v3/template#ConfigData) struct.

### Functions

All of the functions defined in [`StringManipulationFuncs`](https://pkg.go.dev/github.com/vektra/mockery/v3/template#pkg-variables) are available to templated parameters.

Merging Precedence
------------------

Expand Down
57 changes: 57 additions & 0 deletions docs/replace-type.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
---
title: replace-type
---

## Description

The `#!yaml replace-type:` parameter allows you to replace a type in the generated mocks with another type. Take for example the following interface:


```go title="interface.go"
package replace_type

import (
"github.com/vektra/mockery/v3/internal/fixtures/example_project/replace_type/rti/rt1"
"github.com/vektra/mockery/v3/internal/fixtures/example_project/replace_type/rti/rt2"
)

type RType interface {
Replace1(f rt1.RType1)
}
```

You can selectively replace the `rt1.RType1` with a new type if so desired. For example:

```yaml title=".mockery.yml"
replace-type:
github.com/vektra/mockery/v3/internal/fixtures/example_project/replace_type/rti/rt1:
RType1:
pkg-path: github.com/vektra/mockery/v3/internal/fixtures/example_project/replace_type/rti/rt2
type-name: RType2
```

The mock will now replace all instances of `rt1.RType1` with `rt2.RType2`. You can see the before and after of `mockery`-style mocks:

=== "before"

```go
// Replace2 provides a mock function for the type RTypeReplaced1
func (_mock *RTypeReplaced1) Replace1(f rt1.RType1) {
_mock.Called(f)
return
}
```

=== "after"

```go
// Replace2 provides a mock function for the type RTypeReplaced1
func (_mock *RTypeReplaced1) Replace1(f rt2.RType2) {
_mock.Called(f)
return
}
```

## Background

This parameter is useful if you need to need to work around packages that use internal types. Take for example the situation found [here](https://github.com/vektra/mockery/issues/864#issuecomment-2567788637), noted by [RangelReale](https://github.com/RangelReale).
1 change: 1 addition & 0 deletions e2e/test_infinite_mocking.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

# New mocks may legimitately be created, so we run mockery once first
num_files_before=$(find . -type f | wc -l)
export MOCKERY_FORCE_FILE_WRITE="true"
go run github.com/go-task/task/v3/cmd/task mocks.generate
num_files_after=$(find . -type f | wc -l)

Expand Down
2 changes: 1 addition & 1 deletion e2e/test_mockery_generation.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/bin/bash

go run github.com/go-task/task/v3/cmd/task mocks.generate
go run github.com/go-task/task/v3/cmd/task mocks
rt=$?
if [ $rt -ne 0 ]; then
echo "ERROR: non-zero return code from mockery"
Expand Down
8 changes: 0 additions & 8 deletions e2e/test_recursive_package_with_only_autogenerated_files.sh

This file was deleted.

27 changes: 13 additions & 14 deletions internal/cmd/mockery.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,11 @@ import (
pkg "github.com/vektra/mockery/v3/internal"
"github.com/vektra/mockery/v3/internal/logging"
"github.com/vektra/mockery/v3/internal/stackerr"
"github.com/vektra/mockery/v3/template"
"golang.org/x/tools/go/packages"
)

var (
ErrCfgFileNotFound = errors.New("config file not found")
)
var ErrCfgFileNotFound = errors.New("config file not found")

func NewRootCmd() (*cobra.Command, error) {
var pFlags *pflag.FlagSet
Expand Down Expand Up @@ -81,18 +80,18 @@ func Execute() {
if err != nil {
os.Exit(1)
}
if cmd.Execute(); err != nil {
if err := cmd.Execute(); err != nil {
os.Exit(1)
}
}

type RootApp struct {
Config pkg.RootConfig
Config template.RootConfig
}

func GetRootApp(ctx context.Context, flags *pflag.FlagSet) (*RootApp, error) {
r := &RootApp{}
config, _, err := pkg.NewRootConfig(ctx, flags)
config, _, err := template.NewRootConfig(ctx, flags)
if err != nil {
return nil, stackerr.NewStackErrf(err, "failed to get config")
}
Expand All @@ -113,7 +112,7 @@ type InterfaceCollection struct {
outFilePath *pathlib.Path
srcPkg *packages.Package
outPkgName string
interfaces []*pkg.Interface
interfaces []*template.Interface
template string
}

Expand All @@ -122,19 +121,19 @@ func NewInterfaceCollection(
outFilePath *pathlib.Path,
srcPkg *packages.Package,
outPkgName string,
template string,
templ string,
) *InterfaceCollection {
return &InterfaceCollection{
srcPkgPath: srcPkgPath,
outFilePath: outFilePath,
srcPkg: srcPkg,
outPkgName: outPkgName,
interfaces: make([]*pkg.Interface, 0),
template: template,
interfaces: make([]*template.Interface, 0),
template: templ,
}
}

func (i *InterfaceCollection) Append(ctx context.Context, iface *pkg.Interface) error {
func (i *InterfaceCollection) Append(ctx context.Context, iface *template.Interface) error {
collectionFilepath := i.outFilePath.String()
interfaceFilepath := iface.Config.FilePath().String()
log := zerolog.Ctx(ctx).With().
Expand Down Expand Up @@ -258,7 +257,7 @@ func (r *RootApp) Run() error {
}
if err := mockFileToInterfaces[filePath.String()].Append(
ctx,
pkg.NewInterface(
template.NewInterface(
iface.Name,
iface.FileName,
iface.File,
Expand Down Expand Up @@ -313,8 +312,8 @@ func (r *RootApp) Run() error {
fileLog.Err(err).Msg("can't determine if outfile exists")
return fmt.Errorf("determining if outfile exists: %w", err)
}
if outFileExists {
fileLog.Error().Msg("output file exists, can't write mocks")
if outFileExists && !packageConfig.Config.ForceFileWrite {
fileLog.Error().Bool("force-file-write", packageConfig.Config.ForceFileWrite).Msg("output file exists, can't write mocks")
return fmt.Errorf("outfile exists")
}

Expand Down
9 changes: 6 additions & 3 deletions internal/cmd/showconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import (
"github.com/knadh/koanf/providers/structs"
"github.com/knadh/koanf/v2"
"github.com/spf13/cobra"
pkg "github.com/vektra/mockery/v3/internal"
"github.com/vektra/mockery/v3/internal/logging"
"github.com/vektra/mockery/v3/template"
)

func NewShowConfigCmd() *cobra.Command {
Expand All @@ -24,13 +24,16 @@ func NewShowConfigCmd() *cobra.Command {
}

ctx := log.WithContext(context.Background())
conf, _, err := pkg.NewRootConfig(ctx, cmd.Parent().PersistentFlags())
conf, _, err := template.NewRootConfig(ctx, cmd.Parent().PersistentFlags())
if err != nil {
return err
}

k := koanf.New("|")
k.Load(structs.Provider(conf, "koanf"), nil)
if err := k.Load(structs.Provider(conf, "koanf"), nil); err != nil {
log.Err(err).Msg("failed to load config")
return err
}
b, _ := k.Marshal(koanfYAML.Parser())
fmt.Println(string(b))

Expand Down
2 changes: 1 addition & 1 deletion internal/errors.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package pkg
package internal

import "fmt"

Expand Down
Loading
Loading