Skip to content

Commit e307bc6

Browse files
authored
Add back replace-type (#898)
* Add back `replace-types` Port the `replace-type` parameter into mockery v3. This changes the config schema used in the v2 replace-type parameter to be more grokable. This is also a practical matter: the somewhat complex parsing mechanism in v2 is replaced by simple struct attributes. The implementation here is quite different from v2. The templating system in v3 requires type information for all types, and thus we cannot do simple string replacements. We have to call `packages.Load` on the referenced type so we can get real type information. This means that `replace-type` will incur additional latency. This latency penalty, however, grants us additional correctness of implementation: the mock templates will have full type information, and if something about the `replace-type` parameter is wrong (either package path or type name don't exist), mockery will explicitly log this as an error. This does _not_ implement replacements of type constraints as done in v2: #750. This work still needs to be done. Per #864 * Additional documentation * Add docs and hint in log message on how to enable force-file-write.
1 parent 85c4718 commit e307bc6

35 files changed

+650
-173
lines changed

.github/workflows/documentation.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name: documentation
22
on:
33
push:
4-
branches: [ v3 ]
4+
branches: [ master, v3 ]
55
permissions:
66
contents: write
77
jobs:
@@ -28,4 +28,4 @@ jobs:
2828
- name: Deploy docs
2929
run: "mike deploy --push --update-aliases $(grep VERSION mockery-tools.env | cut -d'=' -f 2 | cut -d'.' -f1-2) v3"
3030
env:
31-
GOOGLE_ANALYTICS_KEY: ${{ secrets.GOOGLE_ANALYTICS_KEY }}
31+
GOOGLE_ANALYTICS_KEY: ${{ secrets.GOOGLE_ANALYTICS_KEY }}

.github/workflows/reusable-testing.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ jobs:
2727
go-version: ${{ matrix.go_vers }}
2828

2929
- name: Download dependencies
30-
run: go mod download
30+
run: go mod download -x
3131

3232
- name: Test
3333
run: go run github.com/go-task/task/v3/cmd/task test.ci

.github/workflows/tag-and-release.yml

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,11 @@ on:
66
permissions:
77
contents: write
88
jobs:
9-
# TODO: temporarily disable testing during alpha development
10-
#test:
11-
# uses: ./.github/workflows/reusable-testing.yml
9+
test:
10+
uses: ./.github/workflows/reusable-testing.yml
1211
tag:
1312
runs-on: ubuntu-latest
14-
#needs: test
13+
needs: test
1514
outputs:
1615
tag_result: ${{ steps.tag.outputs.tag_result }}
1716
requested_version: ${{ steps.tag.outputs.requested_version }}
@@ -96,4 +95,4 @@ jobs:
9695
GITHUB_TOKEN: ${{ secrets.GORELEASER_GITHUB_TOKEN }}
9796
HOMEBREW_TAP_TOKEN: ${{ secrets.GORELEASER_HOMEBREW_TAP_TOKEN }}
9897
GORELEASER_CURRENT_TAG: ${{ needs.tag.outputs.requested_version }}
99-
#GORELEASER_PREVIOUS_TAG: ${{ needs.tag.outputs.previous_version }}
98+
#GORELEASER_PREVIOUS_TAG: ${{ needs.tag.outputs.previous_version }}

.github/workflows/testing-dispatch.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,4 @@ jobs:
1212
test:
1313
uses: ./.github/workflows/reusable-testing.yml
1414
with:
15-
ref: ${{ inputs.ref }}
15+
ref: ${{ inputs.ref }}

.github/workflows/testing.yml

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,8 @@ name: Go Test
22

33
on:
44
pull_request:
5-
branches: [v3]
5+
branches: [ master, v3 ]
66

77
jobs:
88
test:
9-
runs-on: ubuntu-latest
10-
steps:
11-
- uses: actions/checkout@v2
12-
with:
13-
fetch-depth: 0
14-
- uses: ./.github/workflows/reusable-testing.yml
15-
9+
uses: ./.github/workflows/reusable-testing.yml

.mockery.yml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,20 @@ template-data:
1010
boilerplate-file: "./.boilerplate.txt"
1111
packages:
1212
github.com/vektra/mockery/v3/internal/fixtures/buildtag/comment:
13+
github.com/vektra/mockery/v3/internal/fixtures/example_project/replace_type:
14+
config:
15+
recursive: True
16+
interfaces:
17+
RType:
18+
configs:
19+
- {}
20+
- mockname: RTypeReplaced1
21+
replace-type:
22+
github.com/vektra/mockery/v3/internal/fixtures/example_project/replace_type/rti/rt1:
23+
RType1:
24+
pkg-path: github.com/vektra/mockery/v3/internal/fixtures/example_project/replace_type/rti/rt2
25+
type-name: RType2
26+
1327
github.com/vektra/mockery/v3/internal/fixtures:
1428
interfaces:
1529
RequesterVariadic:

Taskfile.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ tasks:
1212
sources:
1313
- "**/*.go"
1414
cmds:
15-
- go fmt ./...
15+
- gofumpt -l -w .
1616

1717
mocks:
1818
desc: generate new mocks from scratch
@@ -83,11 +83,11 @@ tasks:
8383
- ./e2e/run_all.sh
8484

8585
test.ci:
86-
deps: [fmt, lint]
86+
deps: [lint]
8787
cmds:
88-
- task: mocks.remove
89-
- task: mocks.generate
88+
- task: mocks
9089
- task: test
90+
- task: mocks.remove
9191
- task: test.e2e
9292

9393
default:

docs/configuration.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ Parameter Descriptions
5757
| `exclude-subpkg-regex` | :fontawesome-solid-x: | `#!yaml []` | A list of regular expressions that denote which subpackages should be excluded when `#!yaml recursive: true` |
5858
| `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. |
5959
| `filename` | :fontawesome-solid-check: | `#!yaml "mock_{{.InterfaceName}}.go"` | The name of the file the mock will reside in. |
60+
| `force-file-write` | :fontawesome-solid-x: | `#!yaml false` | When set to `#!yaml force-file-write: true`, mockery will forcibly overwrite any existing files. |
6061
| `formatter` | :fontawesome-solid-x: | `#!yaml "goimports"` | The formatter to use on the rendered template. Choices are: `gofmt`, `goimports`, `noop`. |
6162
| `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`. |
6263
| `log-level` | :fontawesome-solid-x: | `#!yaml "info"` | Set the level of the logger |
@@ -65,11 +66,25 @@ Parameter Descriptions
6566
| [`packages`](features.md#packages-configuration) | :fontawesome-solid-x: | `#!yaml null` | A dictionary containing configuration describing the packages and interfaces to generate mocks for. |
6667
| `pkgname` | :fontawesome-solid-check: | `#!yaml "{{.SrcPackageName}}" | The `#!go package name` given to the generated mock files. |
6768
| [`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. |
69+
| [`replace-type`](replace-type.md) | :fontawesome-solid-x: | `#!yaml {}` | Use this parameter to specify type replacements. |
6870
| `tags` | :fontawesome-solid-x: | `#!yaml ""` | A space-separated list of additional build tags to load packages. |
6971
| `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`. |
7072
| `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. |
7173

7274

75+
Config Templates
76+
----------------
77+
78+
Parameters marked as being templated have access to a number of template variables and functions.
79+
80+
### Variables
81+
82+
The variables provided are specified in the [`ConfigData`](https://pkg.go.dev/github.com/vektra/mockery/v3/template#ConfigData) struct.
83+
84+
### Functions
85+
86+
All of the functions defined in [`StringManipulationFuncs`](https://pkg.go.dev/github.com/vektra/mockery/v3/template#pkg-variables) are available to templated parameters.
87+
7388
Merging Precedence
7489
------------------
7590

docs/replace-type.md

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
---
2+
title: replace-type
3+
---
4+
5+
## Description
6+
7+
The `#!yaml replace-type:` parameter allows you to replace a type in the generated mocks with another type. Take for example the following interface:
8+
9+
10+
```go title="interface.go"
11+
package replace_type
12+
13+
import (
14+
"github.com/vektra/mockery/v3/internal/fixtures/example_project/replace_type/rti/rt1"
15+
"github.com/vektra/mockery/v3/internal/fixtures/example_project/replace_type/rti/rt2"
16+
)
17+
18+
type RType interface {
19+
Replace1(f rt1.RType1)
20+
}
21+
```
22+
23+
You can selectively replace the `rt1.RType1` with a new type if so desired. For example:
24+
25+
```yaml title=".mockery.yml"
26+
replace-type:
27+
github.com/vektra/mockery/v3/internal/fixtures/example_project/replace_type/rti/rt1:
28+
RType1:
29+
pkg-path: github.com/vektra/mockery/v3/internal/fixtures/example_project/replace_type/rti/rt2
30+
type-name: RType2
31+
```
32+
33+
The mock will now replace all instances of `rt1.RType1` with `rt2.RType2`. You can see the before and after of `mockery`-style mocks:
34+
35+
=== "before"
36+
37+
```go
38+
// Replace2 provides a mock function for the type RTypeReplaced1
39+
func (_mock *RTypeReplaced1) Replace1(f rt1.RType1) {
40+
_mock.Called(f)
41+
return
42+
}
43+
```
44+
45+
=== "after"
46+
47+
```go
48+
// Replace2 provides a mock function for the type RTypeReplaced1
49+
func (_mock *RTypeReplaced1) Replace1(f rt2.RType2) {
50+
_mock.Called(f)
51+
return
52+
}
53+
```
54+
55+
## Background
56+
57+
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).

e2e/test_infinite_mocking.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

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

0 commit comments

Comments
 (0)