mirror of
https://github.com/romdo/go-validate.git
synced 2026-02-18 23:56:41 +00:00
chore(ci/lint/config): update golangci-lint configuration and workflows
Refactor the golangci-lint configuration to use the latest version and update GitHub Actions workflows. Key changes include: - Update golangci-lint to v2.6 - Update GitHub Actions to use latest checkout and setup-go actions - Update Go versions in test matrix - Remove deprecated cache steps - Update Makefile golangci-lint tool version - Minor documentation formatting improvements
This commit is contained in:
92
.github/workflows/ci.yml
vendored
92
.github/workflows/ci.yml
vendored
@@ -7,28 +7,23 @@ jobs:
|
|||||||
name: Lint
|
name: Lint
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0
|
||||||
- name: golangci-lint
|
- uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0
|
||||||
uses: golangci/golangci-lint-action@v2
|
|
||||||
with:
|
with:
|
||||||
version: v1.42
|
go-version-file: go.mod
|
||||||
env:
|
- name: golangci-lint
|
||||||
VERBOSE: "true"
|
uses: golangci/golangci-lint-action@4afd733a84b1f43292c63897423277bb7f4313a9 # v8.0.0
|
||||||
|
with:
|
||||||
|
version: v2.6
|
||||||
|
|
||||||
tidy:
|
tidy:
|
||||||
name: Tidy
|
name: Tidy
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0
|
||||||
- uses: actions/setup-go@v2
|
- uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0
|
||||||
with:
|
with:
|
||||||
go-version: 1.15
|
go-version-file: go.mod
|
||||||
- uses: actions/cache@v2
|
|
||||||
with:
|
|
||||||
path: ~/go/pkg/mod
|
|
||||||
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
|
||||||
restore-keys: |
|
|
||||||
${{ runner.os }}-go-
|
|
||||||
- name: Check if mods are tidy
|
- name: Check if mods are tidy
|
||||||
run: make check-tidy
|
run: make check-tidy
|
||||||
|
|
||||||
@@ -63,31 +58,31 @@ jobs:
|
|||||||
# github-token: ${{ secrets.GITHUB_TOKEN }}
|
# github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
# auto-push: false
|
# auto-push: false
|
||||||
|
|
||||||
cov:
|
# cov:
|
||||||
name: Coverage
|
# name: Coverage
|
||||||
runs-on: ubuntu-latest
|
# runs-on: ubuntu-latest
|
||||||
steps:
|
# steps:
|
||||||
- uses: actions/checkout@v2
|
# - uses: actions/checkout@v2
|
||||||
- uses: actions/setup-go@v2
|
# - uses: actions/setup-go@v2
|
||||||
with:
|
# with:
|
||||||
go-version: 1.15
|
# go-version: 1.15
|
||||||
- uses: actions/cache@v2
|
# - uses: actions/cache@v2
|
||||||
with:
|
# with:
|
||||||
path: ~/go/pkg/mod
|
# path: ~/go/pkg/mod
|
||||||
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
# key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
||||||
restore-keys: |
|
# restore-keys: |
|
||||||
${{ runner.os }}-go-
|
# ${{ runner.os }}-go-
|
||||||
- name: Publish coverage
|
# - name: Publish coverage
|
||||||
uses: paambaati/codeclimate-action@v2.7.4
|
# uses: paambaati/codeclimate-action@v2.7.4
|
||||||
env:
|
# env:
|
||||||
VERBOSE: "true"
|
# VERBOSE: "true"
|
||||||
GOMAXPROCS: 4
|
# GOMAXPROCS: 4
|
||||||
CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
|
# CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
|
||||||
with:
|
# with:
|
||||||
coverageCommand: make cov
|
# coverageCommand: make cov
|
||||||
prefix: github.com/${{ github.repository }}
|
# prefix: github.com/${{ github.repository }}
|
||||||
coverageLocations: |
|
# coverageLocations: |
|
||||||
${{ github.workspace }}/coverage.out:gocov
|
# ${{ github.workspace }}/coverage.out:gocov
|
||||||
|
|
||||||
test:
|
test:
|
||||||
name: Test
|
name: Test
|
||||||
@@ -98,22 +93,19 @@ jobs:
|
|||||||
go_version:
|
go_version:
|
||||||
- "1.15"
|
- "1.15"
|
||||||
- "1.16"
|
- "1.16"
|
||||||
- "1.17"
|
- "1.18"
|
||||||
|
- "1.20"
|
||||||
|
- "1.25"
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 #v5.0.0
|
||||||
- uses: actions/setup-go@v2
|
- uses: actions/setup-go@44694675825211faa026b3c33043df3e48a5fa00 # v6.0.0
|
||||||
with:
|
with:
|
||||||
go-version: ${{ matrix.terraform_version }}
|
go-version-file: go.mod
|
||||||
- uses: actions/cache@v2
|
|
||||||
with:
|
|
||||||
path: ~/go/pkg/mod
|
|
||||||
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
|
|
||||||
restore-keys: |
|
|
||||||
${{ runner.os }}-go-
|
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
run: make test
|
run: make test
|
||||||
env:
|
env:
|
||||||
VERBOSE: "true"
|
VERBOSE: "true"
|
||||||
|
|
||||||
# benchmark-store:
|
# benchmark-store:
|
||||||
# name: Store benchmarks
|
# name: Store benchmarks
|
||||||
# runs-on: ubuntu-latest
|
# runs-on: ubuntu-latest
|
||||||
|
|||||||
126
.golangci.yml
126
.golangci.yml
@@ -1,50 +1,25 @@
|
|||||||
linters-settings:
|
version: "2"
|
||||||
funlen:
|
run:
|
||||||
lines: 100
|
modules-download-mode: readonly
|
||||||
statements: 150
|
allow-parallel-runners: true
|
||||||
goconst:
|
|
||||||
min-occurrences: 5
|
|
||||||
gocyclo:
|
|
||||||
min-complexity: 20
|
|
||||||
golint:
|
|
||||||
min-confidence: 0
|
|
||||||
govet:
|
|
||||||
check-shadowing: true
|
|
||||||
enable-all: true
|
|
||||||
disable:
|
|
||||||
- fieldalignment
|
|
||||||
lll:
|
|
||||||
line-length: 80
|
|
||||||
tab-width: 4
|
|
||||||
maligned:
|
|
||||||
suggest-new: true
|
|
||||||
misspell:
|
|
||||||
locale: US
|
|
||||||
|
|
||||||
linters:
|
linters:
|
||||||
disable-all: true
|
default: none
|
||||||
enable:
|
enable:
|
||||||
- asciicheck
|
- asciicheck
|
||||||
- bodyclose
|
- bodyclose
|
||||||
- deadcode
|
|
||||||
- depguard
|
|
||||||
- dupl
|
- dupl
|
||||||
- durationcheck
|
- durationcheck
|
||||||
- errcheck
|
- errcheck
|
||||||
- errorlint
|
- errorlint
|
||||||
- exhaustive
|
- exhaustive
|
||||||
- exportloopref
|
|
||||||
- funlen
|
- funlen
|
||||||
- gochecknoinits
|
- gochecknoinits
|
||||||
- goconst
|
- goconst
|
||||||
- gocritic
|
- gocritic
|
||||||
- gocyclo
|
- gocyclo
|
||||||
- godot
|
- godot
|
||||||
- gofumpt
|
|
||||||
- goimports
|
|
||||||
- goprintffuncname
|
- goprintffuncname
|
||||||
- gosec
|
- gosec
|
||||||
- gosimple
|
|
||||||
- govet
|
- govet
|
||||||
- importas
|
- importas
|
||||||
- ineffassign
|
- ineffassign
|
||||||
@@ -60,40 +35,69 @@ linters:
|
|||||||
- rowserrcheck
|
- rowserrcheck
|
||||||
- sqlclosecheck
|
- sqlclosecheck
|
||||||
- staticcheck
|
- staticcheck
|
||||||
- structcheck
|
|
||||||
- tparallel
|
- tparallel
|
||||||
- typecheck
|
|
||||||
- unconvert
|
- unconvert
|
||||||
- unparam
|
- unparam
|
||||||
- unused
|
- unused
|
||||||
- varcheck
|
|
||||||
- wastedassign
|
- wastedassign
|
||||||
- whitespace
|
- whitespace
|
||||||
|
settings:
|
||||||
issues:
|
funlen:
|
||||||
exclude:
|
lines: 100
|
||||||
- Using the variable on range scope `tt` in function literal
|
statements: 150
|
||||||
- Using the variable on range scope `tc` in function literal
|
goconst:
|
||||||
exclude-rules:
|
min-occurrences: 5
|
||||||
- path: "_test\\.go"
|
gocyclo:
|
||||||
linters:
|
min-complexity: 20
|
||||||
- funlen
|
govet:
|
||||||
- dupl
|
disable:
|
||||||
- goconst
|
- fieldalignment
|
||||||
- source: "^//go:generate "
|
enable-all: true
|
||||||
linters:
|
lll:
|
||||||
- lll
|
line-length: 80
|
||||||
- source: "`json:"
|
tab-width: 4
|
||||||
linters:
|
misspell:
|
||||||
- lll
|
locale: US
|
||||||
- source: "`yaml:"
|
exclusions:
|
||||||
linters:
|
generated: lax
|
||||||
- lll
|
presets:
|
||||||
- source: "`form:"
|
- comments
|
||||||
linters:
|
- common-false-positives
|
||||||
- lll
|
- legacy
|
||||||
|
- std-error-handling
|
||||||
run:
|
rules:
|
||||||
timeout: 2m
|
- linters:
|
||||||
allow-parallel-runners: true
|
- dupl
|
||||||
modules-download-mode: readonly
|
- funlen
|
||||||
|
- goconst
|
||||||
|
path: _test\.go
|
||||||
|
- linters:
|
||||||
|
- lll
|
||||||
|
source: "^//go:generate "
|
||||||
|
- linters:
|
||||||
|
- lll
|
||||||
|
source: "`json:"
|
||||||
|
- linters:
|
||||||
|
- lll
|
||||||
|
source: "`yaml:"
|
||||||
|
- linters:
|
||||||
|
- lll
|
||||||
|
source: "`form:"
|
||||||
|
- path: (.+)\.go$
|
||||||
|
text: Using the variable on range scope `tt` in function literal
|
||||||
|
- path: (.+)\.go$
|
||||||
|
text: Using the variable on range scope `tc` in function literal
|
||||||
|
paths:
|
||||||
|
- third_party$
|
||||||
|
- builtin$
|
||||||
|
- examples$
|
||||||
|
formatters:
|
||||||
|
enable:
|
||||||
|
- gofumpt
|
||||||
|
- goimports
|
||||||
|
exclusions:
|
||||||
|
generated: lax
|
||||||
|
paths:
|
||||||
|
- third_party$
|
||||||
|
- builtin$
|
||||||
|
- examples$
|
||||||
|
|||||||
2
Makefile
2
Makefile
@@ -48,7 +48,7 @@ endef
|
|||||||
|
|
||||||
$(eval $(call tool,godoc,golang.org/x/tools/cmd/godoc))
|
$(eval $(call tool,godoc,golang.org/x/tools/cmd/godoc))
|
||||||
$(eval $(call tool,gofumports,mvdan.cc/gofumpt/gofumports))
|
$(eval $(call tool,gofumports,mvdan.cc/gofumpt/gofumports))
|
||||||
$(eval $(call tool,golangci-lint,github.com/golangci/golangci-lint/cmd/golangci-lint@v1.42))
|
$(eval $(call tool,golangci-lint,github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.6))
|
||||||
$(eval $(call tool,gomod,github.com/Helcaraxan/gomod))
|
$(eval $(call tool,gomod,github.com/Helcaraxan/gomod))
|
||||||
|
|
||||||
.PHONY: tools
|
.PHONY: tools
|
||||||
|
|||||||
98
validate.go
98
validate.go
@@ -1,13 +1,13 @@
|
|||||||
// Package validate is yet another Go struct/object validation package, with a
|
// Package validate is yet another Go struct/object validation package, with a
|
||||||
// focus on simplicity, flexibility, and full control over validation logic.
|
// focus on simplicity, flexibility, and full control over validation logic.
|
||||||
//
|
//
|
||||||
// Interface
|
// # Interface
|
||||||
//
|
//
|
||||||
// To add validation to any type, simply implement the Validatable interface:
|
// To add validation to any type, simply implement the Validatable interface:
|
||||||
//
|
//
|
||||||
// type Validatable interface {
|
// type Validatable interface {
|
||||||
// Validate() error
|
// Validate() error
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// To mark a object as failing validation, the Validate method simply needs to
|
// To mark a object as failing validation, the Validate method simply needs to
|
||||||
// return a error.
|
// return a error.
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
// can be fully validated, and the nested path to each object is tracked and
|
// can be fully validated, and the nested path to each object is tracked and
|
||||||
// reported back any validation errors.
|
// reported back any validation errors.
|
||||||
//
|
//
|
||||||
// Multiple Errors
|
// # Multiple Errors
|
||||||
//
|
//
|
||||||
// Multiple errors can be reported from the Validate method using one of the
|
// Multiple errors can be reported from the Validate method using one of the
|
||||||
// available Append helper functions which append errors together. Under the
|
// available Append helper functions which append errors together. Under the
|
||||||
@@ -25,53 +25,53 @@
|
|||||||
// a single error return type, and you can in fact just directly use multierr in
|
// a single error return type, and you can in fact just directly use multierr in
|
||||||
// the a type's Validate method.
|
// the a type's Validate method.
|
||||||
//
|
//
|
||||||
// Structs and Field-specific Errors
|
// # Structs and Field-specific Errors
|
||||||
//
|
//
|
||||||
// When validating a struct, you are likely to have multiple errors for multiple
|
// When validating a struct, you are likely to have multiple errors for multiple
|
||||||
// fields. To specify which field on the struct the error relates to, you have
|
// fields. To specify which field on the struct the error relates to, you have
|
||||||
// to return a *validate.Error instead of a normal Go error type. For example:
|
// to return a *validate.Error instead of a normal Go error type. For example:
|
||||||
//
|
//
|
||||||
// type Book struct {
|
// type Book struct {
|
||||||
// Title string
|
// Title string
|
||||||
// Author string
|
// Author string
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// func (s *Book) Validate() error {
|
// func (s *Book) Validate() error {
|
||||||
// var errs error
|
// var errs error
|
||||||
//
|
//
|
||||||
// if s.Title == "" {
|
// if s.Title == "" {
|
||||||
// errs = validate.Append(errs, &validate.Error{
|
// errs = validate.Append(errs, &validate.Error{
|
||||||
// Field: "Title", Msg: "is required",
|
// Field: "Title", Msg: "is required",
|
||||||
// })
|
// })
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// if s.Author == "" {
|
// if s.Author == "" {
|
||||||
// // Yields the same result as the Title field check above.
|
// // Yields the same result as the Title field check above.
|
||||||
// errs = validate.AppendFieldError(errs, "Author", "is required")
|
// errs = validate.AppendFieldError(errs, "Author", "is required")
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// return errs
|
// return errs
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// With the above example, if you validate a empty *Book:
|
// With the above example, if you validate a empty *Book:
|
||||||
//
|
//
|
||||||
// err := validate.Validate(&Book{})
|
// err := validate.Validate(&Book{})
|
||||||
// for _, e := range validate.Errors(err) {
|
// for _, e := range validate.Errors(err) {
|
||||||
// fmt.Println(e.Error())
|
// fmt.Println(e.Error())
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// The following errors would be printed:
|
// The following errors would be printed:
|
||||||
//
|
//
|
||||||
// Title: is required
|
// Title: is required
|
||||||
// Kind: is required
|
// Kind: is required
|
||||||
//
|
//
|
||||||
// Error type
|
// # Error type
|
||||||
//
|
//
|
||||||
// All errors will be wrapped in a *Error before being returned, which is used
|
// All errors will be wrapped in a *Error before being returned, which is used
|
||||||
// to keep track of the path and field the error relates to. There are various
|
// to keep track of the path and field the error relates to. There are various
|
||||||
// helpers available to create Error instances.
|
// helpers available to create Error instances.
|
||||||
//
|
//
|
||||||
// Handling Validation Errors
|
// # Handling Validation Errors
|
||||||
//
|
//
|
||||||
// As mentioned above, multiple errors are wrapped up into a single error return
|
// As mentioned above, multiple errors are wrapped up into a single error return
|
||||||
// value using go.uber.org/multierr. You can access all errors individually with
|
// value using go.uber.org/multierr. You can access all errors individually with
|
||||||
@@ -79,7 +79,7 @@
|
|||||||
// function is just wrapper around multierr.Errors(), so you could use that
|
// function is just wrapper around multierr.Errors(), so you could use that
|
||||||
// instead if you prefer.
|
// instead if you prefer.
|
||||||
//
|
//
|
||||||
// Struct Field Tags
|
// # Struct Field Tags
|
||||||
//
|
//
|
||||||
// Fields on a struct which customize the name via a json, yaml, or form field
|
// Fields on a struct which customize the name via a json, yaml, or form field
|
||||||
// tag, will automatically have the field name converted to the name in the tag
|
// tag, will automatically have the field name converted to the name in the tag
|
||||||
@@ -88,7 +88,7 @@
|
|||||||
// You can customize the field name conversion logic by creating a custom
|
// You can customize the field name conversion logic by creating a custom
|
||||||
// Validator instance, and calling FieldNameFunc() on it.
|
// Validator instance, and calling FieldNameFunc() on it.
|
||||||
//
|
//
|
||||||
// Nested Validatable Objects
|
// # Nested Validatable Objects
|
||||||
//
|
//
|
||||||
// All items/fields on any structs, maps, slices or arrays which are encountered
|
// All items/fields on any structs, maps, slices or arrays which are encountered
|
||||||
// will be validated if they implement the Validatable interface. While
|
// will be validated if they implement the Validatable interface. While
|
||||||
@@ -103,30 +103,30 @@
|
|||||||
// As an example, if our Book struct from above is nested within the following
|
// As an example, if our Book struct from above is nested within the following
|
||||||
// structs:
|
// structs:
|
||||||
//
|
//
|
||||||
// type Order struct {
|
// type Order struct {
|
||||||
// Items []*Item `json:"items"`
|
// Items []*Item `json:"items"`
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// type Item struct {
|
// type Item struct {
|
||||||
// Book *Book `json:"book"`
|
// Book *Book `json:"book"`
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// And we have a Order where the book in the second Item has a empty Author
|
// And we have a Order where the book in the second Item has a empty Author
|
||||||
// field:
|
// field:
|
||||||
//
|
//
|
||||||
// err := validate.Validate(&Order{
|
// err := validate.Validate(&Order{
|
||||||
// Items: []*Item{
|
// Items: []*Item{
|
||||||
// {Book: &Book{Title: "The Traveler", Author: "John Twelve Hawks"}},
|
// {Book: &Book{Title: "The Traveler", Author: "John Twelve Hawks"}},
|
||||||
// {Book: &Book{Title: "The Firm"}},
|
// {Book: &Book{Title: "The Firm"}},
|
||||||
// },
|
// },
|
||||||
// })
|
// })
|
||||||
// for _, e := range validate.Errors(err) {
|
// for _, e := range validate.Errors(err) {
|
||||||
// fmt.Println(e.Error())
|
// fmt.Println(e.Error())
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// Then we would get the following error:
|
// Then we would get the following error:
|
||||||
//
|
//
|
||||||
// items.1.book.Author: is required
|
// items.1.book.Author: is required
|
||||||
//
|
//
|
||||||
// Note how both "items" and "book" are lower cased thanks to the json tags on
|
// Note how both "items" and "book" are lower cased thanks to the json tags on
|
||||||
// the struct fields, while our Book struct does not have a json tag for the
|
// the struct fields, while our Book struct does not have a json tag for the
|
||||||
|
|||||||
Reference in New Issue
Block a user