Skip to content

Commit 5aadc25

Browse files
authored
Add an option to override the protovalidate validator (#23)
Validator instances are not cheap, so by default use the global validator instead of allocating a new one in the server handlers. Add options to allow users to override the validator if needed. The other changes are code hygiene - updating to support the last two versions of Go and bumping golangci-lint to the latest v2.
1 parent 50d074e commit 5aadc25

20 files changed

Lines changed: 236 additions & 194 deletions

File tree

.github/workflows/ci.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ jobs:
1515
runs-on: ubuntu-latest
1616
strategy:
1717
matrix:
18-
go-version: [1.23.x, 1.24.x, 1.25.x]
18+
go-version: [1.25.x, 1.26.x]
1919
steps:
2020
- name: Checkout Code
2121
uses: actions/checkout@v6
@@ -32,5 +32,5 @@ jobs:
3232
# conflicting guidance, run only on the most recent supported version.
3333
# For the same reason, only check generated code on the most recent
3434
# supported version.
35-
if: matrix.go-version == '1.25.x'
35+
if: matrix.go-version == '1.26.x'
3636
run: make checkgenerate && make lint

.golangci.yml

Lines changed: 95 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,6 @@
1-
linters-settings:
2-
errcheck:
3-
check-type-assertions: true
4-
forbidigo:
5-
forbid:
6-
- '^fmt\.Print'
7-
- '^log\.'
8-
- '^print$'
9-
- '^println$'
10-
- '^panic$'
11-
godox:
12-
# TODO, OPT, etc. comments are fine to commit. Use FIXME comments for
13-
# temporary hacks, and use godox to prevent committing them.
14-
keywords: [FIXME]
15-
varnamelen:
16-
ignore-decls:
17-
- T any
18-
- i int
19-
- wg sync.WaitGroup
20-
- id string
1+
version: "2"
212
linters:
22-
enable-all: true
3+
default: all
234
disable:
245
- cyclop # covered by gocyclo
256
- depguard # unnecessary for small libraries
@@ -28,78 +9,108 @@ linters:
289
- funlen # rely on code review to limit function length
2910
- gochecknoglobals # many exceptions
3011
- gocognit # dubious "cognitive overhead" quantification
31-
- gofumpt # prefer standard gofmt
32-
- goimports # rely on gci instead
33-
- gomnd # some unnamed constants are okay
3412
- inamedparam # not standard style
3513
- interfacebloat # many exceptions
3614
- ireturn # "accept interfaces, return structs" isn't ironclad
3715
- lll # don't want hard limits for line length
3816
- maintidx # covered by gocyclo
3917
- nilnil # allow this
4018
- nlreturn # generous whitespace violates house style
19+
- noinlineerr # excess scope violates house style
4120
- testifylint # does not want us to use assert
4221
- testpackage # internal tests are fine
4322
- thelper # we want to print out the whole stack
4423
- wrapcheck # don't _always_ need to wrap errors
4524
- wsl # generous whitespace violates house style
46-
issues:
47-
exclude-dirs-use-default: false
48-
exclude-rules:
49-
- linters:
50-
- revive
51-
path: check/client.go
52-
test: "CheckCallOption"
53-
- linters:
54-
- revive
55-
path: check/check_service_handler.go
56-
test: "CheckServiceHandlerOption"
57-
- linters:
58-
- exhaustive
59-
path: option/options.go
60-
text: "reflect.Pointer|reflect.Ptr"
61-
- linters:
62-
- gocritic
63-
path: check/file.go
64-
text: "commentFormatting"
65-
- linters:
66-
- gocritic
67-
path: check/location.go
68-
text: "commentFormatting"
69-
- linters:
70-
- unparam
71-
path: check/category_spec.go
72-
- linters:
73-
- unparam
74-
path: check/annotation.go
75-
- linters:
76-
- unparam
77-
path: check/response.go
78-
- linters:
79-
- unparam
80-
path: info/plugin_info.go
81-
- linters:
82-
- varnamelen
83-
path: check/internal/example
84-
- linters:
85-
- dupl
86-
path: check/checkutil/breaking.go
87-
- linters:
88-
- varnamelen
89-
path: check/checkutil/breaking.go
90-
- linters:
91-
- varnamelen
92-
path: check/checkutil/lint.go
93-
- linters:
94-
- varnamelen
95-
path: check/checkutil/util.go
96-
- linters:
97-
- varnamelen
98-
path: internal/pkg/xslices/xslices.go
99-
- linters:
100-
- revive
101-
path: internal/pkg/compare/compare.go
102-
- linters:
103-
- gosec
104-
path: check/checktest/checktest.go
105-
text: "G115:"
25+
- wsl_v5 # generous whitespace violates house style
26+
settings:
27+
errcheck:
28+
check-type-assertions: true
29+
forbidigo:
30+
forbid:
31+
- pattern: ^fmt\.Print
32+
- pattern: ^log\.
33+
- pattern: ^print$
34+
- pattern: ^println$
35+
- pattern: ^panic$
36+
godox:
37+
# TODO, OPT, etc. comments are fine to commit. Use FIXME comments for
38+
# temporary hacks, and use godox to prevent committing them.
39+
keywords:
40+
- FIXME
41+
varnamelen:
42+
ignore-decls:
43+
- T any
44+
- i int
45+
- wg sync.WaitGroup
46+
- id string
47+
exclusions:
48+
generated: lax
49+
presets:
50+
- comments
51+
- common-false-positives
52+
- legacy
53+
- std-error-handling
54+
rules:
55+
- linters:
56+
- revive
57+
path: check/client.go
58+
text: CheckCallOption
59+
- linters:
60+
- revive
61+
path: check/check_service_handler.go
62+
text: stutter
63+
- linters:
64+
- exhaustive
65+
path: option/options.go
66+
text: reflect.Pointer|reflect.Ptr
67+
- linters:
68+
- gocritic
69+
path: check/file.go
70+
text: commentFormatting
71+
- linters:
72+
- gocritic
73+
path: check/location.go
74+
text: commentFormatting
75+
- linters:
76+
- unparam
77+
path: check/category_spec.go
78+
- linters:
79+
- unparam
80+
path: check/annotation.go
81+
- linters:
82+
- unparam
83+
path: check/response.go
84+
- linters:
85+
- unparam
86+
path: info/plugin_info.go
87+
- linters:
88+
- varnamelen
89+
path: check/internal/example
90+
- linters:
91+
- dupl
92+
path: check/checkutil/breaking.go
93+
- linters:
94+
- varnamelen
95+
path: check/checkutil/breaking.go
96+
- linters:
97+
- varnamelen
98+
path: check/checkutil/lint.go
99+
- linters:
100+
- varnamelen
101+
path: check/checkutil/util.go
102+
- linters:
103+
- varnamelen
104+
path: internal/pkg/xslices/xslices.go
105+
- linters:
106+
- revive
107+
path: internal/pkg/compare/compare.go
108+
- linters:
109+
- gosec
110+
path: check/checktest/checktest.go
111+
text: 'G115:'
112+
formatters:
113+
enable:
114+
- gci
115+
exclusions:
116+
generated: lax

Makefile

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,8 @@ export GOBIN := $(abspath $(BIN))
1212
COPYRIGHT_YEARS := 2024-2025
1313
LICENSE_IGNORE := --ignore testdata/
1414

15-
BUF_VERSION := v1.50.0
16-
GO_MOD_GOTOOLCHAIN := go1.23.5
17-
GOLANGCI_LINT_VERSION := v1.63.4
18-
# https://github.com/golangci/golangci-lint/issues/4837
19-
GOLANGCI_LINT_GOTOOLCHAIN := $(GO_MOD_GOTOOLCHAIN)
15+
BUF_VERSION := v1.67.0
16+
GOLANGCI_LINT_VERSION := v2.11.4
2017
#GO_GET_PKGS :=
2118

2219
.PHONY: help
@@ -48,11 +45,11 @@ install: ## Install all binaries
4845
.PHONY: lint
4946
lint: $(BIN)/golangci-lint ## Lint
5047
go vet ./...
51-
GOTOOLCHAIN=$(GOLANGCI_LINT_GOTOOLCHAIN) golangci-lint run --modules-download-mode=readonly --timeout=3m0s
48+
golangci-lint run --modules-download-mode=readonly --timeout=3m0s
5249

5350
.PHONY: lintfix
5451
lintfix: $(BIN)/golangci-lint ## Automatically fix some lint errors
55-
GOTOOLCHAIN=$(GOLANGCI_LINT_GOTOOLCHAIN) golangci-lint run --fix --modules-download-mode=readonly --timeout=3m0s
52+
golangci-lint run --fix --modules-download-mode=readonly --timeout=3m0s
5653

5754
.PHONY: generate
5855
generate: $(BIN)/buf $(BIN)/protoc-gen-pluginrpc-go $(BIN)/license-header ## Regenerate code and licenses
@@ -65,7 +62,6 @@ generate: $(BIN)/buf $(BIN)/protoc-gen-pluginrpc-go $(BIN)/license-header ## Reg
6562

6663
.PHONY: upgrade
6764
upgrade: ## Upgrade dependencies
68-
go mod edit -toolchain=$(GO_MOD_GOTOOLCHAIN)
6965
go get -u -t ./... $(GO_GET_PKGS)
7066
go mod tidy -v
7167

@@ -84,7 +80,7 @@ $(BIN)/license-header: Makefile
8480

8581
$(BIN)/golangci-lint: Makefile
8682
@mkdir -p $(@D)
87-
GOTOOLCHAIN=$(GOLANGCI_LINT_GOTOOLCHAIN) go install github.com/golangci/golangci-lint/cmd/golangci-lint@$(GOLANGCI_LINT_VERSION)
83+
go install github.com/golangci/golangci-lint/v2/cmd/golangci-lint@$(GOLANGCI_LINT_VERSION)
8884

8985
.PHONY: $(BIN)/protoc-gen-pluginrpc-go
9086
$(BIN)/protoc-gen-pluginrpc-go:

check/category.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ type Category interface {
3535
//
3636
// This uniquely identifies the Category.
3737
ID() string
38-
// A user-displayable purpose of the category.
38+
// Purpose is a user-displayable purpose of the category.
3939
//
4040
// Always present.
4141
Purpose() string

check/check_service_handler.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,14 @@ func CheckServiceHandlerWithParallelism(parallelism int) CheckServiceHandlerOpti
5555
}
5656
}
5757

58+
// CheckServiceHandlerWithValidator allows overriding the default validator used by the handler.
59+
// By default, [protovalidate.GlobalValidator] is used.
60+
func CheckServiceHandlerWithValidator(validator protovalidate.Validator) CheckServiceHandlerOption {
61+
return func(checkServiceHandlerOptions *checkServiceHandlerOptions) {
62+
checkServiceHandlerOptions.validator = validator
63+
}
64+
}
65+
5866
// *** PRIVATE ***
5967

6068
type checkServiceHandler struct {
@@ -118,9 +126,9 @@ func newCheckServiceHandler(spec *Spec, options ...CheckServiceHandlerOption) (*
118126
ruleIDToRule[id] = rule
119127
ruleIDToIndex[id] = i
120128
}
121-
validator, err := protovalidate.New()
122-
if err != nil {
123-
return nil, err
129+
validator := checkServiceHandlerOptions.validator
130+
if validator == nil {
131+
validator = protovalidate.GlobalValidator
124132
}
125133
return &checkServiceHandler{
126134
spec: spec,
@@ -300,6 +308,7 @@ func (c *checkServiceHandler) getCategoriesAndNextPageToken(pageSize int, pageTo
300308

301309
type checkServiceHandlerOptions struct {
302310
parallelism int
311+
validator protovalidate.Validator
303312
}
304313

305314
func newCheckServiceHandlerOptions() *checkServiceHandlerOptions {

check/check_service_handler_test.go

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
package check
1616

1717
import (
18-
"context"
1918
"testing"
2019

2120
checkv1 "buf.build/gen/go/bufbuild/bufplugin/protocolbuffers/go/buf/plugin/check/v1"
@@ -39,7 +38,7 @@ func TestCheckServiceHandlerUniqueFiles(t *testing.T) {
3938
require.NoError(t, err)
4039

4140
_, err = checkServiceHandler.Check(
42-
context.Background(),
41+
t.Context(),
4342
&checkv1.CheckRequest{
4443
FileDescriptors: []*descriptorv1.FileDescriptor{
4544
{
@@ -62,7 +61,7 @@ func TestCheckServiceHandlerUniqueFiles(t *testing.T) {
6261
require.NoError(t, err)
6362

6463
_, err = checkServiceHandler.Check(
65-
context.Background(),
64+
t.Context(),
6665
&checkv1.CheckRequest{
6766
FileDescriptors: []*descriptorv1.FileDescriptor{
6867
{
@@ -85,7 +84,7 @@ func TestCheckServiceHandlerUniqueFiles(t *testing.T) {
8584
require.Equal(t, pluginrpc.CodeInvalidArgument, pluginrpcError.Code())
8685

8786
_, err = checkServiceHandler.Check(
88-
context.Background(),
87+
t.Context(),
8988
&checkv1.CheckRequest{
9089
FileDescriptors: []*descriptorv1.FileDescriptor{
9190
{
@@ -129,7 +128,7 @@ func TestCheckServiceHandlerNoSourceCodeInfo(t *testing.T) {
129128
require.NoError(t, err)
130129

131130
_, err = checkServiceHandler.Check(
132-
context.Background(),
131+
t.Context(),
133132
&checkv1.CheckRequest{
134133
FileDescriptors: []*descriptorv1.FileDescriptor{
135134
{

check/checktest/checktest.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ type CheckTest struct {
7676
// - Call Check on the Client.
7777
// - Compare the resulting Annotations with the ExpectedAnnotations, failing if there is a mismatch.
7878
func (c CheckTest) Run(t *testing.T) {
79-
ctx := context.Background()
79+
ctx := t.Context()
8080

8181
require.NotNil(t, c.Request)
8282
require.NotNil(t, c.Spec)

0 commit comments

Comments
 (0)